15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/utils.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlsafe.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlsecurity.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <htiframe.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mshtml.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shlobj.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_version_info.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_tokenizer.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_local.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_bstr.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_comptr.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_variant.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/automation_messages.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths_internal.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/chrome_frame_distribution.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/chrome_tab.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/extra_system_apis.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/html_utils.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/navigation_constraints.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/policy_settings.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/registry_list_preferences_holder.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/simple_resource_loader.h"
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/models/menu_model.h"
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/url_canon.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::win::RegKey;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that these values are all lower case and are compared to
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// lower-case-transformed values.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kGCFProtocol[] = "gcf";
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kBodyTag[] = L"body";
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kContentAttribName[] = L"content";
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeContentPrefix[] = L"chrome=";
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeMimeType[] = L"application/chromepage";
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeProtocolPrefix[] = L"gcf:";
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kHttpEquivAttribName[] = L"http-equiv";
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kIexploreProfileName[] = L"iexplore";
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kMetaTag[] = L"meta";
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kRundllProfileName[] = L"rundll32";
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kXUACompatValue[] = L"x-ua-compatible";
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Registry key and value names related to Chrome Frame configuration options.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kAllowUnsafeURLs[] = L"AllowUnsafeURLs";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeFrameConfigKey[] = L"Software\\Google\\ChromeFrame";
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kEnableBuggyBhoIntercept[] = L"EnableBuggyBhoIntercept";
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kEnableGCFRendererByDefault[] = L"IsDefaultRenderer";
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kExcludeUAFromDomainList[] = L"ExcludeUAFromDomain";
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kPatchProtocols[] = L"PatchProtocols";
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kRenderInGCFUrlList[] = L"RenderInGcfUrls";
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kRenderInHostUrlList[] = L"RenderInHostUrls";
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const wchar_t kChromeFramePersistNPAPIReg[] = L"PersistNPAPIReg";
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAttachExternalTabPrefix[] = "attach_external_tab";
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Indicates that we are running in a test environment, where execptions, etc
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are handled by the chrome test crash server.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeFrameHeadlessMode[] = L"ChromeFrameHeadlessMode";
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Indicates that we are running in an environment that expects chrome renderer
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// accessibility to be enabled for use in automation tests.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeFrameAccessibleMode[] = L"ChromeFrameAccessibleMode";
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Indicates that we are running in an environment that wishes to avoid
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DLL pinning, such as the perf tests.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeFrameUnpinnedMode[] = L"kChromeFrameUnpinnedMode";
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Controls whether we download subresources, etc on the chrome frame page in
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the background worker thread. Defaults to true.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kUseBackgroundThreadForSubResources[]
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    = L"BackgroundHTTPWorkerThread";
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {1AF32B6C-A3BA-48B9-B24E-8AA9C41F6ECD}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const IID IID_IWebBrowserPriv2IE7 = { 0x1AF32B6C, 0xA3BA, 0x48B9,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0xB2, 0x4E, 0x8A, 0xA9, 0xC4, 0x1F, 0x6E, 0xCD } };
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {3ED72303-6FFC-4214-BA90-FAF1862DEC8A}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const IID IID_IWebBrowserPriv2IE8 = { 0x3ED72303, 0x6FFC, 0x4214,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0xBA, 0x90, 0xFA, 0xF1, 0x86, 0x2D, 0xEC, 0x8A } };
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {486F6159-9F3F-4827-82D4-283CEF397733}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const IID IID_IWebBrowserPriv2IE8XP = { 0x486F6159, 0x9F3F, 0x4827,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0x82, 0xD4, 0x28, 0x3C, 0xEF, 0x39, 0x77, 0x33 } };
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {38339692-0BC9-46CB-8E5C-4677A5C83DD5}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const IID IID_IWebBrowserPriv2IE8XPBeta = { 0x38339692, 0x0BC9, 0x46CB,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0x8E, 0x5C, 0x46, 0x77, 0xA5, 0xC8, 0x3D, 0xD5 } };
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A flag used to signal when an active browser instance on the current thread
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is loading a Chrome Frame document.  There's no reference stored with the
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pointer so it should not be dereferenced and used for comparison against a
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// living instance only.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<base::ThreadLocalPointer<IBrowserService> >
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_tls_browser_for_cf_navigation = LAZY_INSTANCE_INITIALIZER;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Holds the cached preferences for the per-url render type settings.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<RegistryListPreferencesHolder>::Leaky
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_render_type_for_url_holder;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Holds the cached preferences for the per-url user agent filter.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<RegistryListPreferencesHolder>::Leaky
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_user_agent_filter_holder;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // end anonymous namespace
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT UtilRegisterTypeLib(HINSTANCE tlb_instance,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            LPCOLESTR index,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bool for_current_user_only) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CComBSTR path;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CComPtr<ITypeLib> type_lib;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = AtlLoadTypeLib(tlb_instance, index, &path, &type_lib);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SUCCEEDED(hr)) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = UtilRegisterTypeLib(type_lib, path, NULL, for_current_user_only);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT UtilUnRegisterTypeLib(HINSTANCE tlb_instance,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LPCOLESTR index,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool for_current_user_only) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CComBSTR path;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CComPtr<ITypeLib> type_lib;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = AtlLoadTypeLib(tlb_instance, index, &path, &type_lib);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SUCCEEDED(hr)) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = UtilUnRegisterTypeLib(type_lib, for_current_user_only);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT UtilRegisterTypeLib(LPCWSTR typelib_path,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bool for_current_user_only) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NULL == typelib_path) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_INVALIDARG;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CComBSTR path;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CComPtr<ITypeLib> type_lib;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = ::LoadTypeLib(typelib_path, &type_lib);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SUCCEEDED(hr)) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = UtilRegisterTypeLib(type_lib,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             typelib_path,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             NULL,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             for_current_user_only);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT UtilUnRegisterTypeLib(LPCWSTR typelib_path,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool for_current_user_only) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CComPtr<ITypeLib> type_lib;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = ::LoadTypeLib(typelib_path, &type_lib);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SUCCEEDED(hr)) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = UtilUnRegisterTypeLib(type_lib, for_current_user_only);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT UtilRegisterTypeLib(ITypeLib* typelib,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            LPCWSTR typelib_path,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            LPCWSTR help_dir,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bool for_current_user_only) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef HRESULT(WINAPI *RegisterTypeLibPrototype)(ITypeLib FAR* type_lib,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    OLECHAR FAR* full_path,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    OLECHAR FAR* help_dir);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LPCSTR function_name =
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for_current_user_only ? "RegisterTypeLibForUser" : "RegisterTypeLib";
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterTypeLibPrototype reg_tlb =
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<RegisterTypeLibPrototype>(
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GetProcAddress(GetModuleHandle(_T("oleaut32.dll")),
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         function_name));
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NULL == reg_tlb) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_FAIL;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reg_tlb(typelib,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const_cast<OLECHAR*>(typelib_path),
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const_cast<OLECHAR*>(help_dir));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT UtilUnRegisterTypeLib(ITypeLib* typelib,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool for_current_user_only) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NULL == typelib) {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_INVALIDARG;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef HRESULT(WINAPI *UnRegisterTypeLibPrototype)(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      REFGUID libID,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned short wVerMajor,  // NOLINT
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned short wVerMinor,  // NOLINT
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LCID lcid,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SYSKIND syskind);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LPCSTR function_name =
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for_current_user_only ? "UnRegisterTypeLibForUser" : "UnRegisterTypeLib";
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnRegisterTypeLibPrototype unreg_tlb =
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<UnRegisterTypeLibPrototype>(
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GetProcAddress(GetModuleHandle(_T("oleaut32.dll")),
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         function_name));
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NULL == unreg_tlb) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_FAIL;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TLIBATTR* tla = NULL;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = typelib->GetLibAttr(&tla);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SUCCEEDED(hr)) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = unreg_tlb(tla->guid,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   tla->wMajorVerNum,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   tla->wMinorVerNum,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   tla->lcid,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   tla->syskind);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typelib->ReleaseTLibAttr(tla);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UtilRemovePersistentNPAPIMarker() {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserDistribution* cf_dist = BrowserDistribution::GetDistribution();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring cf_state_key_path(cf_dist->GetStateKey());
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegKey cf_state_key;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LONG result = cf_state_key.Open(HKEY_LOCAL_MACHINE, cf_state_key_path.c_str(),
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  KEY_SET_VALUE);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == ERROR_SUCCESS)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = cf_state_key.DeleteValue(kChromeFramePersistNPAPIReg);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT UtilGetXUACompatContentValue(const std::wstring& html_string,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     std::wstring* content_value) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!content_value) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_POINTER;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fail fast if the string X-UA-Compatible isn't in html_string
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (StringToLowerASCII(html_string).find(kXUACompatValue) ==
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::wstring::npos) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_FAIL;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HTMLScanner scanner(html_string.c_str());
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build the list of meta tags that occur before the body tag is hit.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HTMLScanner::StringRangeList tag_list;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scanner.GetTagsByName(kMetaTag, &tag_list, kBodyTag);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Search the list of meta tags for one with an http-equiv="X-UA-Compatible"
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // attribute.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HTMLScanner::StringRange attribute;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string search_attribute_ascii(WideToASCII(kXUACompatValue));
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HTMLScanner::StringRangeList::const_iterator tag_list_iter(tag_list.begin());
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; tag_list_iter != tag_list.end(); tag_list_iter++) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!tag_list_iter->GetTagAttribute(kHttpEquivAttribName, &attribute)) {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We found an http-equiv meta tag, check its value using the ascii
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // case-insensitive comparison method.
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!attribute.LowerCaseEqualsASCII(search_attribute_ascii.c_str())) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We found our X-UA-Compatible meta tag so look for and extract
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the value of the content attribute.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!tag_list_iter->GetTagAttribute(kContentAttribName, &attribute)) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Found the content string, copy and return.
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content_value->assign(attribute.Copy());
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return E_FAIL;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayVersionMismatchWarning(HWND parent,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const std::string& server_version) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Obtain the current module version.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<FileVersionInfo> module_version_info(
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FileVersionInfo::CreateFileVersionInfoForCurrentModule());
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 version_string(module_version_info->file_version());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring wide_server_version;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (server_version.empty()) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wide_server_version = SimpleResourceLoader::Get(IDS_VERSIONUNKNOWN);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wide_server_version = ASCIIToWide(server_version);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring title = SimpleResourceLoader::Get(IDS_VERSIONMISMATCH_HEADER);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring message;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SStringPrintf(&message,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      SimpleResourceLoader::Get(IDS_VERSIONMISMATCH).c_str(),
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      wide_server_version.c_str(),
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      version_string.c_str());
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::MessageBox(parent, message.c_str(), title.c_str(), MB_OK);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string CreateJavascript(const std::string& function_name,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::string args) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string script_string = "javascript:";
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  script_string += function_name + "(";
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!args.empty()) {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    script_string += "'";
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    script_string += args;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    script_string += "'";
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  script_string += ")";
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return script_string;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AddRefModule::AddRefModule() {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(tommi): Override the module's Lock/Unlock methods to call
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  npapi::SetValue(NPPVpluginKeepLibraryInMemory) and keep the dll loaded
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  while the module's refcount is > 0.  Only do this when we're being
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  used as an NPAPI module.
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  _pAtlModule->Lock();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AddRefModule::~AddRefModule() {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  _pAtlModule->Unlock();
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsChrome(RendererType renderer_type) {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(renderer_type, RENDERER_TYPE_UNDETERMINED);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LE(renderer_type, RENDERER_TYPE_OTHER);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return renderer_type >= RENDERER_TYPE_CHROME_MIN &&
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    renderer_type <= RENDERER_TYPE_CHROME_MAX;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kIEImageName[] = "iexplore.exe";
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring GetHostProcessName(bool include_extension) {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath exe;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (PathService::Get(base::FILE_EXE, &exe))
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exe = exe.BaseName();
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!include_extension) {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exe = exe.RemoveExtension();
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return exe.value();
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserType GetBrowserType() {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static BrowserType browser_type = BROWSER_INVALID;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (browser_type == BROWSER_INVALID) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::wstring exe(GetHostProcessName(true));
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!exe.empty()) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::wstring::const_iterator begin = exe.begin();
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::wstring::const_iterator end = exe.end();
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (LowerCaseEqualsASCII(begin, end, kIEImageName)) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        browser_type = BROWSER_IE;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        browser_type = BROWSER_UNKNOWN;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser_type;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 GetIEMajorVersion() {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static uint32 ie_major_version = UINT_MAX;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ie_major_version == UINT_MAX) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wchar_t exe_path[MAX_PATH];
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HMODULE mod = GetModuleHandle(NULL);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetModuleFileName(mod, exe_path, arraysize(exe_path) - 1);
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::wstring exe_name = base::FilePath(exe_path).BaseName().value();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!LowerCaseEqualsASCII(exe_name, kIEImageName)) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ie_major_version = 0;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uint32 high = 0;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uint32 low  = 0;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (GetModuleVersion(mod, &high, &low)) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ie_major_version = HIWORD(high);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ie_major_version = 0;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ie_major_version;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IEVersion GetIEVersion() {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static IEVersion ie_version = IE_INVALID;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ie_version == IE_INVALID) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 major_version = GetIEMajorVersion();
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (major_version) {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 0:
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ie_version = NON_IE;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 6:
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ie_version = IE_6;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 7:
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ie_version = IE_7;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 8:
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ie_version = IE_8;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 9:
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ie_version = IE_9;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ie_version = (major_version >= 10) ? IE_10 : IE_UNSUPPORTED;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ie_version;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetIETemporaryFilesFolder() {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LPITEMIDLIST tif_pidl = NULL;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = SHGetFolderLocation(NULL, CSIDL_INTERNET_CACHE, NULL,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   SHGFP_TYPE_CURRENT, &tif_pidl);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SUCCEEDED(hr) && tif_pidl) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedComPtr<IShellFolder> parent_folder;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LPITEMIDLIST relative_pidl = NULL;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = SHBindToParent(tif_pidl, IID_IShellFolder,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        reinterpret_cast<void**>(parent_folder.Receive()),
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const_cast<LPCITEMIDLIST*>(&relative_pidl));
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr) && relative_pidl) {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      STRRET path = {0};
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = parent_folder->GetDisplayNameOf(relative_pidl,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           SHGDN_NORMAL | SHGDN_FORPARSING,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &path);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(SUCCEEDED(hr));
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::win::ScopedBstr temp_internet_files_bstr;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StrRetToBSTR(&path, relative_pidl, temp_internet_files_bstr.Receive());
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath temp_internet_files(
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          static_cast<BSTR>(temp_internet_files_bstr));
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ILFree(tif_pidl);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return temp_internet_files;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "SHBindToParent failed with Error:" << hr;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ILFree(tif_pidl);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "SHGetFolderLocation for internet cache failed. Error:"
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << hr;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As a last ditch effort we use the SHGetFolderPath function to retrieve the
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // path. This function has a limitation of MAX_PATH.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wchar_t path[MAX_PATH + 1] = {0};
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = SHGetFolderPath(NULL, CSIDL_INTERNET_CACHE, NULL, SHGFP_TYPE_CURRENT,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       path);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SUCCEEDED(hr)) {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath(path);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "SHGetFolderPath for internet cache failed. Error:"
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << hr;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FilePath();
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsIEInPrivate() {
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef BOOL (WINAPI* IEIsInPrivateBrowsingPtr)();
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool incognito_mode = false;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HMODULE h = GetModuleHandle(L"ieframe.dll");
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (h) {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IEIsInPrivateBrowsingPtr IsInPrivate =
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<IEIsInPrivateBrowsingPtr>(GetProcAddress(h,
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "IEIsInPrivateBrowsing"));
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsInPrivate) {
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      incognito_mode = !!IsInPrivate();
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return incognito_mode;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT DoFileDownloadInIE(const wchar_t* url) {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(url);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HMODULE mod = ::GetModuleHandleA("ieframe.dll");
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!mod)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mod = ::GetModuleHandleA("shdocvw.dll");
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!mod) {
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_UNEXPECTED;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef HRESULT (WINAPI* DoFileDownloadFn)(const wchar_t*);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoFileDownloadFn fn = reinterpret_cast<DoFileDownloadFn>(
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::GetProcAddress(mod, "DoFileDownload"));
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(fn);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return fn ? fn(url) : E_UNEXPECTED;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetModuleVersion(HMODULE module, uint32* high, uint32* low) {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(module != NULL)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Please use GetModuleHandle(NULL) to get the process name";
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(high);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ok = false;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRSRC res = FindResource(module,
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<const wchar_t*>(VS_VERSION_INFO), RT_VERSION);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (res) {
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HGLOBAL res_data = LoadResource(module, res);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD version_resource_size = SizeofResource(module, res);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const void* readonly_resource_data = LockResource(res_data);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (readonly_resource_data && version_resource_size) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Copy data as VerQueryValue tries to modify the data. This causes
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // exceptions and heap corruption errors if debugger is attached.
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_ptr<char[]> data(new char[version_resource_size]);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (data.get()) {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        memcpy(data.get(), readonly_resource_data, version_resource_size);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        VS_FIXEDFILEINFO* ver_info = NULL;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UINT info_size = 0;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (VerQueryValue(data.get(), L"\\",
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          reinterpret_cast<void**>(&ver_info), &info_size)) {
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          *high = ver_info->dwFileVersionMS;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (low != NULL)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            *low = ver_info->dwFileVersionLS;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ok = true;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UnlockResource(res_data);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FreeResource(res_data);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ok;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxSubmenuDepth = 10;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Builds a Windows menu from the menu model sent from Chrome.  The
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// caller is responsible for closing the returned HMENU.  This does
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not currently handle bitmaps (e.g. hbmpChecked, hbmpUnchecked or
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// hbmpItem), so checkmarks, radio buttons, and custom icons won't work.
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It also copies over submenus up to a maximum depth of kMaxSubMenuDepth.
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HMENU BuildContextMenuImpl(const ContextMenuModel* menu_model, int depth) {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (depth >= kMaxSubmenuDepth)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HMENU menu = CreatePopupMenu();
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < menu_model->items.size(); i++) {
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ContextMenuModel::Item& item = menu_model->items[i];
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MENUITEMINFO item_info = { 0 };
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item_info.cbSize = sizeof(MENUITEMINFO);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (item.type) {
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ui::MenuModel::TYPE_COMMAND:
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ui::MenuModel::TYPE_CHECK:
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.fType = MFT_STRING;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.wID = item.item_id;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.dwTypeData = const_cast<LPWSTR>(item.label.c_str());
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ui::MenuModel::TYPE_RADIO:
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.fType = MFT_STRING | MFT_RADIOCHECK;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.wID = item.item_id;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.dwTypeData = const_cast<LPWSTR>(item.label.c_str());
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ui::MenuModel::TYPE_SEPARATOR:
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.fMask = MIIM_FTYPE;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.fType = MFT_SEPARATOR;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ui::MenuModel::TYPE_SUBMENU:
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_SUBMENU;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.fType = MFT_STRING;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.wID = item.item_id;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.dwTypeData = const_cast<LPWSTR>(item.label.c_str());
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item_info.hSubMenu = BuildContextMenuImpl(item.submenu, depth + 1);
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED() << "Unsupported MenuModel::ItemType " << item.type;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item_info.fMask |= MIIM_STATE;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item_info.fState =
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (item.checked ? MFS_CHECKED : MFS_UNCHECKED) |
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (item.enabled ? MFS_ENABLED : (MFS_DISABLED | MFS_GRAYED));
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InsertMenuItem(menu, i, TRUE, &item_info);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return menu;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HMENU BuildContextMenu(const ContextMenuModel& menu_model) {
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return BuildContextMenuImpl(&menu_model, 0);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ResolveURL(const std::string& document,
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const std::string& relative) {
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (document.empty()) {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GURL(relative).spec();
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GURL(document).Resolve(relative).spec();
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HaveSameOrigin(const std::string& url1, const std::string& url2) {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL a(url1), b(url2);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ret;
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (a.is_valid() != b.is_valid()) {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Either (but not both) url is invalid, so they can't match.
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = false;
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (!a.is_valid()) {
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Both URLs are invalid (see first check).  Just check if the opaque
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // strings match exactly.
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = url1.compare(url2) == 0;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (a.GetOrigin() != b.GetOrigin()) {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origins don't match.
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = false;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we have a match.
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = true;
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetConfigInt(int default_value, const wchar_t* value_name) {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ret = default_value;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegKey config_key;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey,
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      KEY_QUERY_VALUE) == ERROR_SUCCESS) {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    config_key.ReadValueDW(value_name, reinterpret_cast<DWORD*>(&ret));
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint64 GetConfigInt64(int64 default_value, const wchar_t* value_name) {
664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int64 ret = default_value;
665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RegKey config_key;
666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey,
667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                      KEY_QUERY_VALUE) == ERROR_SUCCESS) {
668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    config_key.ReadInt64(value_name, &ret);
669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return ret;
672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetConfigBool(bool default_value, const wchar_t* value_name) {
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD value = GetConfigInt(default_value, value_name);
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (value != FALSE);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetConfigInt(const wchar_t* value_name, int value) {
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegKey config_key;
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (config_key.Create(HKEY_CURRENT_USER, kChromeFrameConfigKey,
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        KEY_SET_VALUE) == ERROR_SUCCESS) {
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (config_key.WriteValue(value_name, value) == ERROR_SUCCESS) {
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetConfigBool(const wchar_t* value_name, bool value) {
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SetConfigInt(value_name, value);
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool SetConfigInt64(const wchar_t* value_name, int64 value) {
696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RegKey config_key;
697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (config_key.Create(HKEY_CURRENT_USER, kChromeFrameConfigKey,
698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                        KEY_SET_VALUE) == ERROR_SUCCESS) {
699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (config_key.WriteValue(value_name, &value, sizeof(value),
700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              REG_QWORD) == ERROR_SUCCESS) {
701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return true;
702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return false;
706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeleteConfigValue(const wchar_t* value_name) {
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegKey config_key;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey,
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      KEY_WRITE) == ERROR_SUCCESS) {
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (config_key.DeleteValue(value_name) == ERROR_SUCCESS) {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsGcfDefaultRenderer() {
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD is_default = 0;  // NOLINT
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First check policy settings
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicySettings::RendererForUrl renderer =
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PolicySettings::GetInstance()->default_renderer();
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (renderer != PolicySettings::RENDERER_NOT_SPECIFIED) {
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_default = (renderer == PolicySettings::RENDER_IN_CHROME_FRAME);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(tommi): Implement caching for this config value as it gets
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // checked frequently.
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RegKey config_key;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey,
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        KEY_READ) == ERROR_SUCCESS) {
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      config_key.ReadValueDW(kEnableGCFRendererByDefault, &is_default);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_default != 0;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RendererType RendererTypeForUrl(const std::wstring& url) {
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First check if the default renderer settings are specified by policy.
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If so, then that overrides the user settings.
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicySettings::RendererForUrl renderer =
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PolicySettings::GetInstance()->GetRendererForUrl(url.c_str());
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (renderer != PolicySettings::RENDERER_NOT_SPECIFIED) {
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We may know at this point that policy says do NOT render in Chrome Frame.
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // To maintain consistency, we return RENDERER_TYPE_UNDETERMINED so that
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // content sniffing, etc. still take place.
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(tommi): Clarify the intent here.
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (renderer == PolicySettings::RENDER_IN_CHROME_FRAME) ?
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RENDERER_TYPE_CHROME_OPT_IN_URL : RENDERER_TYPE_UNDETERMINED;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(robertshield): Move this into a holder-type class that listens
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for reg change events as well.
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int render_in_cf_by_default = FALSE;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegistryListPreferencesHolder& render_type_for_url_holder =
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      g_render_type_for_url_holder.Get();
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!render_type_for_url_holder.Valid()) {
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const wchar_t* url_list_name = kRenderInGCFUrlList;
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsGcfDefaultRenderer()) {
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url_list_name = kRenderInHostUrlList;
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_in_cf_by_default = TRUE;
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_in_cf_by_default = FALSE;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    render_type_for_url_holder.Init(HKEY_CURRENT_USER,
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    kChromeFrameConfigKey,
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    url_list_name);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(render_type_for_url_holder.Valid());
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RendererType renderer_type =
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_in_cf_by_default ? RENDERER_TYPE_CHROME_DEFAULT_RENDERER :
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                RENDERER_TYPE_UNDETERMINED;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (render_type_for_url_holder.ListMatches(url)) {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    renderer_type = render_in_cf_by_default ?
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RENDERER_TYPE_UNDETERMINED :
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RENDERER_TYPE_CHROME_OPT_IN_URL;
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return renderer_type;
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShouldRemoveUAForUrl(const string16& url) {
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(robertshield): Wire up the stuff in PolicySettings here so the value
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can be specified via group policy.
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(robertshield): Add a default list of exclusions here for site with
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // known bad UA parsing.
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegistryListPreferencesHolder& user_agent_filter_holder =
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      g_user_agent_filter_holder.Get();
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!user_agent_filter_holder.Valid()) {
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    user_agent_filter_holder.Init(HKEY_CURRENT_USER,
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  kChromeFrameConfigKey,
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  kExcludeUAFromDomainList);
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(user_agent_filter_holder.Valid());
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return user_agent_filter_holder.ListMatches(url);
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RegistryListPreferencesHolder& GetRendererTypePreferencesHolderForTesting() {
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_render_type_for_url_holder.Get();
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RegistryListPreferencesHolder& GetUserAgentPreferencesHolderForTesting() {
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_user_agent_filter_holder.Get();
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const wchar_t* headers, IBindCtx* bind_ctx,
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const wchar_t* fragment, IStream* post_data,
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 VARIANT* flags) {
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(browser);
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(moniker);
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bind_ctx);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<IWebBrowser2> web_browser2;
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = DoQueryService(SID_SWebBrowserApp, browser,
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              web_browser2.Receive());
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(web_browser2);
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DLOG_IF(WARNING, FAILED(hr)) << base::StringPrintf(L"SWebBrowserApp 0x%08X",
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     hr);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the data to be downloaded was received in response to a post request
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then we need to reissue the post request.
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedVariant post_data_variant;
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (post_data) {
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RewindStream(post_data);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CComSafeArray<uint8> safe_array_post;
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATSTG stat;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    post_data->Stat(&stat, STATFLAG_NONAME);
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (stat.cbSize.LowPart > 0) {
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string data;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HRESULT hr = E_FAIL;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      while ((hr = ReadStream(post_data, 0xffff, &data)) == S_OK) {
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        safe_array_post.Add(
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            data.size(),
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            reinterpret_cast<unsigned char*>(const_cast<char*>(data.data())));
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        data.clear();
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If we get here it means that the navigation is being reissued for a
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // POST request with no data. To ensure that the new window used as a
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // target to handle the new navigation issues a POST request
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // we need valid POST data. In this case we create a dummy 1 byte array.
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // May not work as expected with some web sites.
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(WARNING) << "Reissuing navigation with empty POST data. May not"
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    << " work as expected";
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      safe_array_post.Create(1);
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    post_data_variant.Set(safe_array_post.Detach());
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a new bind context that's not associated with our callback.
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling RevokeBindStatusCallback doesn't disassociate the callback with
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the bind context in IE7.  The returned bind context has the same
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // implementation of GetRunningObjectTable as the bind context we held which
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // basically delegates to ole32's GetRunningObjectTable.  The object table
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is then used to determine if the moniker is already running and via
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that mechanism is associated with the same internet request as has already
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // been issued.
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(tommi): See if we can get HlinkSimpleNavigateToMoniker to work
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instead.  Looks like we'll need to support IHTMLDocument2 (get_URL in
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // particular), access to IWebBrowser2 etc.
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HlinkSimpleNavigateToMoniker(moniker, url, NULL, host, bind_context,
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                              NULL, 0, 0);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<IUriContainer> uri_container;
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = uri_container.QueryFrom(moniker);
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedVariant headers_var;
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (headers && headers[0])
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers_var.Set(headers);
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (uri_container) {
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // IE7 and IE8.
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IID* interface_ids[] = {
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &IID_IWebBrowserPriv2IE7,
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &IID_IWebBrowserPriv2IE8,
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &IID_IWebBrowserPriv2IE8XP,
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &IID_IWebBrowserPriv2IE8XPBeta,
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedComPtr<IWebBrowserPriv2Common, NULL> browser_priv2;
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < arraysize(interface_ids) && browser_priv2 == NULL;
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         ++i) {
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = web_browser2.QueryInterface(*interface_ids[i],
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          reinterpret_cast<void**>(browser_priv2.Receive()));
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(browser_priv2);
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (browser_priv2) {
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::win::ScopedComPtr<IUri> uri_obj;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uri_container->GetIUri(uri_obj.Receive());
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(uri_obj);
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (GetIEVersion() < IE_9) {
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hr = browser_priv2->NavigateWithBindCtx2(
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                uri_obj, flags, NULL, post_data_variant.AsInput(),
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                headers_var.AsInput(), bind_ctx,
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                const_cast<wchar_t*>(fragment));
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IWebBrowserPriv2CommonIE9* browser_priv2_ie9 =
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            reinterpret_cast<IWebBrowserPriv2CommonIE9*>(browser_priv2.get());
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hr = browser_priv2_ie9->NavigateWithBindCtx2(
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                uri_obj, flags, NULL, post_data_variant.AsInput(),
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                headers_var.AsInput(), bind_ctx,
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                const_cast<wchar_t*>(fragment), 0);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG_IF(WARNING, FAILED(hr))
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << base::StringPrintf(L"NavigateWithBindCtx2 0x%08X", hr);
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // IE6
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LPOLESTR url = NULL;
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr = moniker->GetDisplayName(bind_ctx, NULL, &url))) {
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << __FUNCTION__ << " " << url;
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::win::ScopedComPtr<IWebBrowserPriv> browser_priv;
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (SUCCEEDED(hr = browser_priv.QueryFrom(web_browser2))) {
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL target_url(url);
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // On IE6 if the original URL has a fragment then the navigation
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // attempt is ignored. To workaround this we strip the fragment from
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // the url and initiate the navigation. When the active document loads
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // we retrieve the original url with the fragment from the Navigation
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // manager and use it.
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (target_url.has_ref()) {
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          url_parse::Component comp;
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GURL::Replacements replacements;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          replacements.SetRef("", comp);
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          target_url = target_url.ReplaceComponents(replacements);
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          fragment = NULL;
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::win::ScopedVariant var_url(UTF8ToWide(target_url.spec()).c_str());
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hr = browser_priv->NavigateWithBindCtx(var_url.AsInput(), flags, NULL,
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               post_data_variant.AsInput(),
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               headers_var.AsInput(), bind_ctx,
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const_cast<wchar_t*>(fragment));
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DLOG_IF(WARNING, FAILED(hr))
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << base::StringPrintf(L"NavigateWithBindCtx 0x%08X", hr);
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::CoTaskMemFree(url);
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << base::StringPrintf("GetDisplayName: 0x%08X", hr);
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MarkBrowserOnThreadForCFNavigation(IBrowserService* browser) {
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(browser != NULL);
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(g_tls_browser_for_cf_navigation.Pointer()->Get() == NULL ||
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         g_tls_browser_for_cf_navigation.Pointer()->Get() == browser);
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_tls_browser_for_cf_navigation.Pointer()->Set(browser);
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckForCFNavigation(IBrowserService* browser, bool clear_flag) {
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(browser);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ret = (g_tls_browser_for_cf_navigation.Pointer()->Get() == browser);
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ret && clear_flag)
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_tls_browser_for_cf_navigation.Pointer()->Set(NULL);
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret;
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValidUrlScheme(const GURL& url, bool is_privileged) {
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url.is_empty())
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url.SchemeIs(chrome::kHttpScheme) ||
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url.SchemeIs(chrome::kHttpsScheme) ||
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url.SchemeIs(chrome::kAboutScheme))
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Additional checking for view-source. Allow only http and https
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URLs in view source.
991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (url.SchemeIs(content::kViewSourceScheme)) {
992de1bd3ebc0808574e846315a068b6935d3e72d5fJonathan Dixon    GURL sub_url(url.GetContent());
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sub_url.SchemeIs(chrome::kHttpScheme) ||
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sub_url.SchemeIs(chrome::kHttpsScheme))
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_privileged &&
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (url.SchemeIs(chrome::kDataScheme) ||
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       url.SchemeIs(extensions::kExtensionScheme)))
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetRawHttpHeaders(IWinInetHttpInfo* info) {
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(info);
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string buffer;
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD size = 0;
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD flags = 0;
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD reserved = 0;
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = info->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, NULL, &size,
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &flags, &reserved);
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!size) {
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << "Failed to query HTTP headers size. Error: " << hr;
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer.resize(size + 1);
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = info->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, &buffer[0],
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &size, &flags, &reserved);
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (FAILED(hr)) {
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(WARNING) << "Failed to query HTTP headers. Error: " << hr;
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return buffer;
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSubFrameRequest(IUnknown* service_provider) {
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(service_provider);
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need to be able to get at an IWebBrowser2 if we are to decide whether
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this request originates from a non-top-level frame.
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<IWebBrowser2> web_browser;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = DoQueryService(IID_ITargetFrame2, service_provider,
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              web_browser.Receive());
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_sub_frame_request = false;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_browser) {
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now check to see if we are in a sub-frame.
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedComPtr<IHTMLWindow2> current_frame, parent_frame;
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = DoQueryService(IID_IHTMLWindow2, service_provider,
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        current_frame.Receive());
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (current_frame) {
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Only the top level window will return self when get_parent is called.
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_frame->get_parent(parent_frame.Receive());
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (parent_frame != current_frame) {
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DVLOG(1) << "Sub frame detected";
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        is_sub_frame_request = true;
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "IsSubFrameRequest - no IWebBrowser2";
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_sub_frame_request = true;
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_sub_frame_request;
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsHeadlessMode() {
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool headless = GetConfigBool(false, kChromeFrameHeadlessMode);
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return headless;
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsAccessibleMode() {
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool accessible = GetConfigBool(false, kChromeFrameAccessibleMode);
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return accessible;
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsUnpinnedMode() {
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We only check this value once and then cache it since changing the registry
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // once we've pinned the DLL won't have any effect.
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool unpinned = GetConfigBool(false, kChromeFrameUnpinnedMode);
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return unpinned;
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring GetActualUrlFromMoniker(IMoniker* moniker,
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     IBindCtx* bind_context,
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const std::wstring& bho_url) {
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CComHeapPtr<WCHAR> display_name;
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moniker->GetDisplayName(bind_context, NULL, &display_name);
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring moniker_url = display_name;
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL parsed_url(WideToUTF8(bho_url));
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!parsed_url.has_ref())
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return moniker_url;
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (StartsWith(bho_url, moniker_url, false) &&
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bho_url[moniker_url.length()] == L'#')
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return bho_url;
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return moniker_url;
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsTopLevelWindow(HWND window) {
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  long style = GetWindowLong(window, GWL_STYLE);  // NOLINT
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!(style & WS_CHILD))
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HWND parent = GetParent(window);
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !parent || (parent == GetDesktopWindow());
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RewindStream(IStream* stream) {
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = E_POINTER;
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (stream) {
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LARGE_INTEGER zero = {0};
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ULARGE_INTEGER new_pos = {0};
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = stream->Seek(zero, STREAM_SEEK_SET, &new_pos);
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring GuidToString(const GUID& guid) {
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring ret;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::StringFromGUID2(guid, WriteInto(&ret, 39), 39);
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret;
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32 MapCookieStateToCookieAction(InternetCookieState cookie_state) {
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 cookie_action = COOKIEACTION_NONE;
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (cookie_state) {
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case COOKIE_STATE_UNKNOWN:
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_action = COOKIEACTION_NONE;
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case COOKIE_STATE_ACCEPT:
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_action = COOKIEACTION_ACCEPT;
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case COOKIE_STATE_LEASH:
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_action = COOKIEACTION_LEASH;
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case COOKIE_STATE_DOWNGRADE:
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_action = COOKIEACTION_DOWNGRADE;
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case COOKIE_STATE_REJECT:
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_action = COOKIEACTION_REJECT;
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_action = COOKIEACTION_REJECT;
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cookie_action;
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL GetUrlWithoutFragment(const wchar_t* url) {
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL parsed_url(url);
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parsed_url.has_ref()) {
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_parse::Component comp;
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL::Replacements replacements;
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    replacements.SetRef("", comp);
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed_url = parsed_url.ReplaceComponents(replacements);
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return parsed_url;
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CompareUrlsWithoutFragment(const wchar_t* url1, const wchar_t* url2) {
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL parsed_url1 = GetUrlWithoutFragment(url1);
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL parsed_url2 = GetUrlWithoutFragment(url2);
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return parsed_url1 == parsed_url2;
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string FindReferrerFromHeaders(const wchar_t* headers,
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const wchar_t* additional_headers) {
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string referrer;
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* both_headers[] = { headers, additional_headers };
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; referrer.empty() && i < arraysize(both_headers); ++i) {
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!both_headers[i])
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string raw_headers_utf8 = WideToUTF8(both_headers[i]);
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpUtil::HeadersIterator it(raw_headers_utf8.begin(),
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      raw_headers_utf8.end(), "\r\n");
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (it.GetNext()) {
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (LowerCaseEqualsASCII(it.name(), "referer")) {
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        referrer = it.values();
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return referrer;
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetHttpHeadersFromBinding(IBinding* binding) {
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (binding == NULL) {
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << "GetHttpResponseStatus - no binding_";
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string();
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<IWinInetHttpInfo> info;
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(info.QueryFrom(binding))) {
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << "Failed to QI for IWinInetHttpInfo";
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string();
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetRawHttpHeaders(info);
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetHttpResponseStatusFromBinding(IBinding* binding) {
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (binding == NULL) {
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << "GetHttpResponseStatus - no binding_";
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int http_status = 0;
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<IWinInetHttpInfo> info;
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SUCCEEDED(info.QueryFrom(binding))) {
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char status[10] = {0};
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD buf_size = sizeof(status);
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD flags = 0;
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD reserved = 0;
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(info->QueryInfo(HTTP_QUERY_STATUS_CODE, status, &buf_size,
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  &flags, &reserved))) {
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::StringToInt(status, &http_status);
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Failed to get HTTP status";
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "failed to get IWinInetHttpInfo from binding_";
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return http_status;
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CLIPFORMAT GetTextHtmlClipboardFormat() {
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const CLIPFORMAT text_html = RegisterClipboardFormat(CFSTR_MIME_HTML);
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return text_html;
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsTextHtmlMimeType(const wchar_t* mime_type) {
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return IsTextHtmlClipFormat(RegisterClipboardFormatW(mime_type));
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsTextHtmlClipFormat(CLIPFORMAT cf) {
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cf == GetTextHtmlClipboardFormat();
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSystemProcess() {
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_system = false;
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CAccessToken process_token;
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (process_token.GetProcessToken(TOKEN_QUERY, GetCurrentProcess())) {
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CSid logon_sid;
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (process_token.GetUser(&logon_sid)) {
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_system = logon_sid == Sids::System();
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_system;
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string BindStatus2Str(ULONG bind_status) {
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string s;
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const bindstatus_txt[] = {
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_FINDINGRESOURCE",
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_CONNECTING",
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_REDIRECTING",
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_BEGINDOWNLOADDATA",
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_DOWNLOADINGDATA",
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_ENDDOWNLOADDATA",
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_BEGINDOWNLOADCOMPONENTS",
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_INSTALLINGCOMPONENTS",
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_ENDDOWNLOADCOMPONENTS",
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_USINGCACHEDCOPY",
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_SENDINGREQUEST",
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_CLASSIDAVAILABLE",
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_MIMETYPEAVAILABLE",
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_CACHEFILENAMEAVAILABLE",
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_BEGINSYNCOPERATION",
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_ENDSYNCOPERATION",
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_BEGINUPLOADDATA",
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_UPLOADINGDATA",
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_ENDUPLOADINGDATA",
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_PROTOCOLCLASSID",
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_ENCODING",
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_VERFIEDMIMETYPEAVAILABLE",
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_CLASSINSTALLLOCATION",
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_DECODING",
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_LOADINGMIMEHANDLER",
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_CONTENTDISPOSITIONATTACH",
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_FILTERREPORTMIMETYPE",
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_CLSIDCANINSTANTIATE",
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_IUNKNOWNAVAILABLE",
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_DIRECTBIND",
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_RAWMIMETYPE",
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_PROXYDETECTING",
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_ACCEPTRANGES",
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_COOKIE_SENT",
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_COMPACT_POLICY_RECEIVED",
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_COOKIE_SUPPRESSED",
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_COOKIE_STATE_UNKNOWN",
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_COOKIE_STATE_ACCEPT",
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_COOKIE_STATE_REJECT",
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_COOKIE_STATE_PROMPT",
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_COOKIE_STATE_LEASH",
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_COOKIE_STATE_DOWNGRADE",
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_POLICY_HREF",
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_P3P_HEADER",
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_SESSION_COOKIE_RECEIVED",
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_PERSISTENT_COOKIE_RECEIVED",
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_SESSION_COOKIES_ALLOWED",
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_CACHECONTROL",
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_CONTENTDISPOSITIONFILENAME",
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_MIMETEXTPLAINMISMATCH",
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_PUBLISHERAVAILABLE",
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_DISPLAYNAMEAVAILABLE",
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_SSLUX_NAVBLOCKED",
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_SERVER_MIMETYPEAVAILABLE",
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_SNIFFED_CLASSIDAVAILABLE",
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "BINDSTATUS_64BIT_PROGRESS"
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bind_status >= 1 && bind_status <= BINDSTATUS_64BIT_PROGRESS)
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    s = bindstatus_txt[bind_status - 1];
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    s = base::StringPrintf("UnDoc[%#x]", bind_status);
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return s;
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string PiFlags2Str(DWORD flags) {
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ADD_PI_FLAG(x)  \
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & x) { \
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    s.append(#x ## " "); \
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags &= ~x; \
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string s = " flags ";
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_PARSE_URL);
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_FILTER_MODE);
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_FORCE_ASYNC);
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_USE_WORKERTHREAD);
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_MIMEVERIFICATION);
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_CLSIDLOOKUP);
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_DATAPROGRESS);
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_SYNCHRONOUS);
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_APARTMENTTHREADED);
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_CLASSINSTALL);
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_PASSONBINDCTX);
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_NOMIMEHANDLER);
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_LOADAPPDIRECT);
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PD_FORCE_SWITCH);
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_PI_FLAG(PI_PREFERDEFAULTHANDLER);
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags)
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    s += base::StringPrintf("+UnDoc[%#x]", flags);
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return s;
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef ADD_PI_FLAG
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Bscf2Str(DWORD flags) {
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ADD_BSCF_FLAG(x)  \
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & x) {\
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    s.append(#x ## " "); \
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags &= ~x; \
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string s = " flags ";
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_BSCF_FLAG(BSCF_FIRSTDATANOTIFICATION)
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_BSCF_FLAG(BSCF_INTERMEDIATEDATANOTIFICATION)
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_BSCF_FLAG(BSCF_LASTDATANOTIFICATION)
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_BSCF_FLAG(BSCF_DATAFULLYAVAILABLE)
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_BSCF_FLAG(BSCF_AVAILABLEDATASIZEUNKNOWN)
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_BSCF_FLAG(BSCF_SKIPDRAINDATAFORFILEURLS)
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_BSCF_FLAG(BSCF_64BITLENGTHDOWNLOAD)
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags)
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    s += base::StringPrintf("+UnDoc[%#x]", flags);
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return s;
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef ADD_BSCF_FLAG
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Reads data from a stream into a string.
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT ReadStream(IStream* stream, size_t size, std::string* data) {
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(stream);
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(size, 0u);
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(data);
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD read = 0;
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = stream->Read(WriteInto(data, size + 1), size, &read);
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(hr == S_OK || hr == S_FALSE || hr == E_PENDING);
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (read) {
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data->erase(read);
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_EQ(read, data->length());
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data->clear();
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return S_FALSE if the underlying stream returned S_OK and zero bytes.
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (hr == S_OK)
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = S_FALSE;
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeFrameUrl::ChromeFrameUrl() {
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Reset();
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChromeFrameUrl::Parse(const std::wstring& url) {
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Reset();
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parsed_url_ = GURL(url);
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parsed_url_.is_empty())
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_chrome_protocol_ = parsed_url_.SchemeIs(kGCFProtocol);
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_chrome_protocol_) {
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed_url_ = GURL(url.c_str() + lstrlen(kChromeProtocolPrefix));
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ParseAttachExternalTabUrl();
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChromeFrameUrl::ParseAttachExternalTabUrl() {
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string query = parsed_url_.query();
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!StartsWithASCII(query, kAttachExternalTabPrefix, false)) {
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return parsed_url_.is_valid();
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attach_to_external_tab_ = true;
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringTokenizer tokenizer(query, "&");
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip over kChromeAttachExternalTabPrefix
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tokenizer.GetNext();
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the following items in order.
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. cookie
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2. disposition
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3. dimension.x
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 4. dimension.y
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 5. dimension.width
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6. dimension.height.
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tokenizer.GetNext()) {
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* end_ptr = 0;
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cookie_ = _strtoui64(tokenizer.token().c_str(), &end_ptr, 10);
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tokenizer.GetNext()) {
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disposition_ = atoi(tokenizer.token().c_str());
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tokenizer.GetNext()) {
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dimensions_.set_x(atoi(tokenizer.token().c_str()));
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tokenizer.GetNext()) {
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dimensions_.set_y(atoi(tokenizer.token().c_str()));
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tokenizer.GetNext()) {
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dimensions_.set_width(atoi(tokenizer.token().c_str()));
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tokenizer.GetNext()) {
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dimensions_.set_height(atoi(tokenizer.token().c_str()));
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tokenizer.GetNext()) {
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    profile_name_ = tokenizer.token();
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Escape out special characters like %20, etc.
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    profile_name_ = net::UnescapeURLComponent(profile_name_,
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS);
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeFrameUrl::Reset() {
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attach_to_external_tab_ = false;
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_chrome_protocol_ = false;
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_ = 0;
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dimensions_.SetRect(0, 0, 0, 0);
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disposition_ = 0;
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_name_.clear();
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanNavigate(const GURL& url,
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 NavigationConstraints* navigation_constraints) {
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.is_valid()) {
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "Invalid URL passed to InitiateNavigation: " << url;
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!navigation_constraints) {
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Invalid NavigationConstraints passed in";
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No sanity checks if unsafe URLs are allowed
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (navigation_constraints->AllowUnsafeUrls())
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!navigation_constraints->IsSchemeAllowed(url)) {
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << __FUNCTION__ << " Disallowing navigation to url: " << url;
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!navigation_constraints->IsZoneAllowed(url)) {
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << __FUNCTION__
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  << " Disallowing navigation to restricted url: " << url;
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WaitWithMessageLoop(HANDLE* handles, int count, DWORD timeout) {
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time now = base::Time::Now();
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time wait_until = now + base::TimeDelta::FromMilliseconds(timeout);
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (wait_until >= now) {
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta wait_time = wait_until - now;
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD wait = MsgWaitForMultipleObjects(
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        count, handles, FALSE, static_cast<DWORD>(wait_time.InMilliseconds()),
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        QS_ALLINPUT);
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (wait) {
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WAIT_OBJECT_0:
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WAIT_TIMEOUT:
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       return;
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WAIT_OBJECT_0 + 1: {
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MSG msg = {0};
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          TranslateMessage(&msg);
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          DispatchMessage(&msg);
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default: {
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED() << "Unexpected return from MsgWaitForMultipleObjects :"
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     << wait;
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now = base::Time::Now();
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns -1 if no directive is found, std::numeric_limits<int>::max() if the
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// directive matches all IE versions ('Chrome=1') or the maximum IE version
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// matched ('Chrome=IE7' => 7)
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetXUaCompatibleDirective(const std::string& directive, char delimiter) {
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpUtil::NameValuePairsIterator name_value_pairs(directive.begin(),
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         directive.end(),
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         delimiter);
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Loop through the values until a valid 'Chrome=<FILTER>' entry is found
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (name_value_pairs.GetNext()) {
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!LowerCaseEqualsASCII(name_value_pairs.name_begin(),
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             name_value_pairs.name_end(),
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             "chrome")) {
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string::const_iterator filter_begin = name_value_pairs.value_begin();
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string::const_iterator filter_end = name_value_pairs.value_end();
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t filter_length = filter_end - filter_begin;
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (filter_length == 1 && *filter_begin == '1') {
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return std::numeric_limits<int>::max();
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (filter_length < 3 ||
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !LowerCaseEqualsASCII(filter_begin, filter_begin + 2, "ie") ||
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !isdigit(*(filter_begin + 2))) {  // ensure no leading +/-
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int header_ie_version = 0;
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!base::StringToInt(base::StringPiece(filter_begin + 2,
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             filter_end),
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           &header_ie_version) ||
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        header_ie_version == 0) {  // ensure it's not a sequence of 0's
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The first valid directive we find wins, whether it matches or not
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return header_ie_version;
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return -1;
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckXUaCompatibleDirective(const std::string& directive,
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 int ie_major_version) {
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int header_ie_version = GetXUaCompatibleDirective(directive, ';');
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (header_ie_version == -1) {
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_ie_version = GetXUaCompatibleDirective(directive, ',');
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return header_ie_version >= ie_major_version;
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnumerateKeyValues(HKEY parent_key, const wchar_t* sub_key_name,
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        std::vector<std::wstring>* values) {
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(values);
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::RegistryValueIterator url_list(parent_key, sub_key_name);
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (url_list.Valid()) {
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    values->push_back(url_list.Value());
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++url_list;
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring GetCurrentModuleVersion() {
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<FileVersionInfo> module_version_info(
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FileVersionInfo::CreateFileVersionInfoForCurrentModule());
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(module_version_info.get() != NULL);
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return module_version_info->file_version();
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsChromeFrameDocument(IWebBrowser2* web_browser) {
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!web_browser)
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<IDispatch> doc;
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_browser->get_Document(doc.Receive());
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (doc) {
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Detect if CF is rendering based on whether the document is a
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ChromeActiveDocument. Detecting based on hwnd is problematic as
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the CF Active Document window may not have been created yet.
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedComPtr<IChromeFrame> chrome_frame;
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome_frame.QueryFrom(doc);
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return chrome_frame.get() != NULL;
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IncreaseWinInetConnections(DWORD connections) {
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool wininet_connection_count_updated = false;
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (wininet_connection_count_updated) {
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int connection_options[] = {
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INTERNET_OPTION_MAX_CONNS_PER_SERVER,
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER,
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BOOL ret = FALSE;
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int option_index = 0; option_index < arraysize(connection_options);
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++option_index) {
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD connection_value_size = sizeof(DWORD);
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD current_connection_limit = 0;
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InternetQueryOption(NULL, connection_options[option_index],
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &current_connection_limit, &connection_value_size);
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (current_connection_limit > connections) {
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = InternetSetOption(NULL, connection_options[option_index],
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &connections, connection_value_size);
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ret) {
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wininet_connection_count_updated = true;
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetChromeFrameProfilePath(const string16& profile_name,
16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               base::FilePath* profile_path) {
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::GetChromeFrameUserDataDirectory(profile_path);
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *profile_path = profile_path->Append(profile_name);
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << ": " << profile_path->value();
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1684