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)// chrome_tab.cc : Implementation of DLL Exports.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Need to include this before the ATL headers below.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/chrome_tab.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlsecurity.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <objbase.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/at_exit.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_version_info.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/i18n/icu_util.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging_win.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
22a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/launch.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h"
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/sys_string_conversions.h"
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/google_update_settings.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/bho.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/chrome_active_document.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/chrome_frame_activex.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/chrome_frame_automation.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/chrome_frame_reporting.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/chrome_launcher_utils.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/chrome_protocol.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/dll_redirector.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/exception_barrier.h"
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome_frame/pin_module.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/resource.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/utils.h"
46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "components/variations/entropy_provider.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chrome_frame_resources.h"
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/url_util.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if _ATL_VER >= 0x0C00
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// This was removed between the VS2010 version and the VS2013 version, and
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// the unsuffixed version was repurposed to mean 'S'.
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define UpdateRegistryFromResourceS UpdateRegistryFromResource
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::win::RegKey;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kInternetSettings[] =
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kProtocolHandlers[] =
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"Software\\Classes\\Protocols\\Handler";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kRunOnce[] =
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce";
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kRunKeyName[] = L"ChromeFrameHelper";
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeFrameHelperExe[] = L"chrome_frame_helper.exe";
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeFrameHelperStartupArg[] = L"--startup";
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Window class and window names.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(robertshield): These and other constants need to be refactored into
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a common chrome_frame_constants.h|cc and built into a separate lib
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (either chrome_frame_utils or make another one).
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeFrameHelperWindowClassName[] =
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"ChromeFrameHelperWindowClass";
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeFrameHelperWindowName[] =
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"ChromeFrameHelperWindowName";
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {0562BFC3-2550-45b4-BD8E-A310583D3A6F}
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const GUID kChromeFrameProvider =
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0x562bfc3, 0x2550, 0x45b4,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        { 0xbd, 0x8e, 0xa3, 0x10, 0x58, 0x3d, 0x3a, 0x6f } };
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kPostPlatformUAKey[] =
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\"
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"User Agent\\Post Platform";
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kChromeFramePrefix[] = L"chromeframe/";
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See comments in DllGetClassObject.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LPFNGETCLASSOBJECT g_dll_get_class_object_redir_ptr = NULL;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This function has the side effect of initializing an unprotected
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// vector pointer inside GoogleUrl. If this is called during DLL loading,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it has the effect of avoiding an initialization race on that pointer.
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(siggi): fix GoogleUrl.
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InitGoogleUrl() {
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const char kDummyUrl[] = "http://www.google.com";
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_util::IsStandard(kDummyUrl,
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       url_parse::MakeRange(0, arraysize(kDummyUrl)));
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChromeTabModule : public CAtlDllModuleT<ChromeTabModule> {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef CAtlDllModuleT<ChromeTabModule> ParentClass;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ChromeTabModule() : do_system_registration_(true),
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      crash_reporting_(NULL),
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      icu_initialized_(false) {}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DECLARE_LIBID(LIBID_ChromeTabLib)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CHROMETAB,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "{FD9B1B31-F4D8-436A-8F4F-D3C2E36733D3}")
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override to add our SYSTIME binary value to registry scripts.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See chrome_frame_activex.rgs for usage.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual HRESULT AddCommonRGSReplacements(IRegistrarBase* registrar) throw() {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HRESULT hr = ParentClass::AddCommonRGSReplacements(registrar);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr)) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SYSTEMTIME local_time;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::GetSystemTime(&local_time);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string hex(base::HexEncode(&local_time, sizeof(local_time)));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::StringPiece sp_hex(hex);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = registrar->AddReplacement(L"SYSTIME",
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     base::SysNativeMBToWide(sp_hex).c_str());
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(SUCCEEDED(hr));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr)) {
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath app_path =
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          chrome_launcher::GetChromeExecutablePath().DirName();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = registrar->AddReplacement(L"CHROME_APPPATH",
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     app_path.value().c_str());
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(SUCCEEDED(hr));
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr)) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = registrar->AddReplacement(L"CHROME_APPNAME",
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     chrome::kBrowserProcessExecutableName);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(SUCCEEDED(hr));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Fill in VERSION from the VERSIONINFO stored in the DLL's resources.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<FileVersionInfo> module_version_info(
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FileVersionInfo::CreateFileVersionInfoForCurrentModule());
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(module_version_info != NULL);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::wstring file_version(module_version_info->file_version());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = registrar->AddReplacement(L"VERSION", file_version.c_str());
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(SUCCEEDED(hr));
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr)) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add the directory of chrome_launcher.exe.  This will be the same
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // as the directory for the current DLL.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::wstring module_dir;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath module_path;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (PathService::Get(base::FILE_MODULE, &module_path)) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        module_dir = module_path.DirName().value();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = registrar->AddReplacement(L"CHROME_LAUNCHER_APPPATH",
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     module_dir.c_str());
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(SUCCEEDED(hr));
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr)) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add the filename of chrome_launcher.exe
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = registrar->AddReplacement(L"CHROME_LAUNCHER_APPNAME",
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     chrome_launcher::kLauncherExeBaseName);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(SUCCEEDED(hr));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr)) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add the registry hive to use.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Note: This is ugly as hell. I'd rather use the pMapEntries parameter
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // to CAtlModule::UpdateRegistryFromResource, unfortunately we have a
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // few components that are registered by calling their
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // static T::UpdateRegistry() methods directly, which doesn't allow
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // pMapEntries to be passed through :-(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (do_system_registration_) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hr = registrar->AddReplacement(L"HIVE", L"HKLM");
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hr = registrar->AddReplacement(L"HIVE", L"HKCU");
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(SUCCEEDED(hr));
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr)) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add the Chrome Frame CLSID.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wchar_t cf_clsid[64];
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StringFromGUID2(CLSID_ChromeFrame, &cf_clsid[0], arraysize(cf_clsid));
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = registrar->AddReplacement(L"CHROME_FRAME_CLSID", &cf_clsid[0]);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The module is "locked" when an object takes a reference on it. The first
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // time it is locked, take a reference on crash reporting to bind its lifetime
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to the module and initialize ICU.
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual LONG Lock() throw() {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LONG result = ParentClass::Lock();
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (result == 1) {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK_EQ(crash_reporting_,
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                static_cast<chrome_frame::ScopedCrashReporting*>(NULL));
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      crash_reporting_ = new chrome_frame::ScopedCrashReporting();
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Initialize ICU if this is the first time the module has been locked.
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (!icu_initialized_) {
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        icu_initialized_ = true;
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Best-effort since something is better than nothing here.
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ignore_result(base::i18n::InitializeICU());
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return result;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The module is "unlocked" when an object that had a reference on it is
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // destroyed. The last time it is unlocked, release the reference on crash
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // reporting.
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual LONG Unlock() throw() {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LONG result = ParentClass::Unlock();
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!result) {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK_NE(crash_reporting_,
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                static_cast<chrome_frame::ScopedCrashReporting*>(NULL));
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delete crash_reporting_;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      crash_reporting_ = NULL;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return result;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See comments in AddCommonRGSReplacements
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool do_system_registration_;
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A scoper created when the module is initially locked and destroyed when it
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is finally unlocked. This is not a scoped_ptr since that could cause
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // reporting to shut down at exit, which would lead to problems with the
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // loader lock.
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome_frame::ScopedCrashReporting* crash_reporting_;
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Initially false, this is flipped to true to indicate that ICU has been
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // initialized for the module.
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool icu_initialized_;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeTabModule _AtlModule;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::AtExitManager* g_exit_manager = NULL;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RefreshElevationPolicy() {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t kIEFrameDll[] = L"ieframe.dll";
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kIERefreshPolicy[] = "IERefreshElevationPolicy";
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = E_NOTIMPL;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stick an SEH in the chain to prevent the VEH from picking up on first
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chance exceptions caused by loading ieframe.dll. Use the vanilla
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ExceptionBarrier to report any exceptions that do make their way to us
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // though.
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExceptionBarrier barrier;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HMODULE ieframe_module = LoadLibrary(kIEFrameDll);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ieframe_module) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef HRESULT (__stdcall *IERefreshPolicy)();
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IERefreshPolicy ie_refresh_policy = reinterpret_cast<IERefreshPolicy>(
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetProcAddress(ieframe_module, kIERefreshPolicy));
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ie_refresh_policy) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = ie_refresh_policy();
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = HRESULT_FROM_WIN32(GetLastError());
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FreeLibrary(ieframe_module);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = HRESULT_FROM_WIN32(GetLastError());
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Experimental boot prefetch optimization for Chrome Frame
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If chrome is warmed up during a single reboot, it gets paged
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in for subsequent reboots and the cold startup times essentially
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// look like warm times thereafter! The 'warm up' is done by
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// setting up a 'RunOnce' key during DLLRegisterServer of
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// npchrome_frame.dll.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This works because chrome prefetch becomes part of boot
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// prefetch file ntosboot-b00dfaad.pf and paged in on subsequent
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reboots. As long as the sytem does not undergo significant
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// memory pressure those pages remain in memory and we get pretty
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// amazing startup times, down to about 300 ms from 1200 ms
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The downside is:
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Whether chrome frame is used or not, there's a read penalty
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  (1200-300 =) 900 ms for every boot.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Heavy system memory usage after reboot will nullify the benefits
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  but the user will still pay the cost.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Overall the time saved will always be less than total time spent
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  paging in chrome
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - We are not sure when the chrome 'warm up' will age out from the
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  boot prefetch file.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The idea here is to try this out on chrome frame dev channel
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and see if it produces a significant drift in startup numbers.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT SetupRunOnce() {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT result = E_FAIL;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 channel_name;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::GetVersion() < base::win::VERSION_VISTA &&
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GoogleUpdateSettings::GetChromeChannelAndModifiers(true, &channel_name)) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::transform(channel_name.begin(), channel_name.end(),
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   channel_name.begin(), tolower);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use this only for the dev channel.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (channel_name.find(L"dev") != string16::npos) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HKEY hive = HKEY_CURRENT_USER;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (IsSystemProcess()) {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // For system installs, our updates will be running as SYSTEM which
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // makes writing to a RunOnce key under HKCU not so terribly useful.
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hive = HKEY_LOCAL_MACHINE;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RegKey run_once;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LONG ret = run_once.Create(hive, kRunOnce, KEY_READ | KEY_WRITE);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (ret == ERROR_SUCCESS) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CommandLine run_once_cmd(chrome_launcher::GetChromeExecutablePath());
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        run_once_cmd.AppendSwitchASCII(switches::kAutomationClientChannelID,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "0");
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        run_once_cmd.AppendSwitch(switches::kChromeFrame);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = run_once.WriteValue(L"A",
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  run_once_cmd.GetCommandLineString().c_str());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result = HRESULT_FROM_WIN32(ret);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result = S_FALSE;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We're on a non-XP version of Windows or on a stable channel. Nothing
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // needs doing.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = S_FALSE;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper method called for user-level installs where we don't have admin
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// permissions. Starts up the long running process and registers it to get it
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// started at next boot.
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT SetupUserLevelHelper() {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = S_OK;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove existing run-at-startup entry.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::RemoveCommandFromAutoRun(HKEY_CURRENT_USER, kRunKeyName);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build the chrome_frame_helper command line.
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath module_path;
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath helper_path;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (PathService::Get(base::FILE_MODULE, &module_path)) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    module_path = module_path.DirName();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper_path = module_path.Append(kChromeFrameHelperExe);
3687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!base::PathExists(helper_path)) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If we can't find the helper in the current directory, try looking
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // one up (this is the layout in the build output folder).
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      module_path = module_path.DirName();
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      helper_path = module_path.Append(kChromeFrameHelperExe);
3737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      DCHECK(base::PathExists(helper_path)) <<
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "Could not find chrome_frame_helper.exe.";
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Find window handle of existing instance.
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HWND old_window = FindWindow(kChromeFrameHelperWindowClassName,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 kChromeFrameHelperWindowName);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (base::PathExists(helper_path)) {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::wstring helper_path_cmd(L"\"");
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      helper_path_cmd += helper_path.value();
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      helper_path_cmd += L"\" ";
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      helper_path_cmd += kChromeFrameHelperStartupArg;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add new run-at-startup entry.
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!base::win::AddCommandToAutoRun(HKEY_CURRENT_USER, kRunKeyName,
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          helper_path_cmd)) {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hr = E_FAIL;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "Could not add helper process to auto run key.";
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Start new instance.
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::LaunchOptions options;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      options.start_hidden = true;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool launched = base::LaunchProcess(helper_path.value(), options, NULL);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!launched) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hr = E_FAIL;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PLOG(DFATAL) << "Could not launch helper process.";
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Kill old instance using window handle.
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (IsWindow(old_window)) {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BOOL result = PostMessage(old_window, WM_CLOSE, 0, 0);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!result) {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          PLOG(ERROR) << "Failed to post close message to old helper process: ";
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = E_UNEXPECTED;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To delete the user agent, set value to NULL.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The is_system parameter indicates whether this is a per machine or a per
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// user installation.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT SetChromeFrameUA(bool is_system, const wchar_t* value) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = E_FAIL;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HKEY parent_hive = is_system ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegKey ua_key;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LONG reg_result = ua_key.Create(parent_hive, kPostPlatformUAKey,
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  KEY_READ | KEY_WRITE);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (reg_result == ERROR_SUCCESS) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure that we unregister ChromeFrame UA strings registered previously
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wchar_t value_name[MAX_PATH + 1] = {};
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wchar_t value_data[MAX_PATH + 1] = {};
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD value_index = 0;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (value_index < ua_key.GetValueCount()) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DWORD name_size = arraysize(value_name);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DWORD value_size = arraysize(value_data);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DWORD type = 0;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LRESULT ret = ::RegEnumValue(ua_key.Handle(), value_index, value_name,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   &name_size, NULL, &type,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   reinterpret_cast<BYTE*>(value_data),
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   &value_size);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (ret == ERROR_SUCCESS) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (StartsWith(value_name, kChromeFramePrefix, false)) {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ua_key.DeleteValue(value_name);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++value_index;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::wstring chrome_frame_ua_value_name = kChromeFramePrefix;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome_frame_ua_value_name += GetCurrentModuleVersion();
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ua_key.WriteValue(chrome_frame_ua_value_name.c_str(), value);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = S_OK;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << __FUNCTION__ << ": " << kPostPlatformUAKey
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                << ", error code = " << reg_result;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = HRESULT_FROM_WIN32(reg_result);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SecurityDescBackup {
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit SecurityDescBackup(const std::wstring& backup_key)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : backup_key_name_(backup_key) {}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~SecurityDescBackup() {}
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Save given security descriptor to the backup key.
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SaveSecurity(const CSecurityDesc& sd) {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CString str;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!sd.ToString(&str))
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RegKey backup_key(HKEY_LOCAL_MACHINE, backup_key_name_.c_str(),
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      KEY_READ | KEY_WRITE);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (backup_key.Valid()) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return backup_key.WriteValue(NULL, str.GetString()) == ERROR_SUCCESS;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restore security descriptor from backup key to given key name.
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool RestoreSecurity(const wchar_t* key_name) {
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::wstring sddl;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ReadBackupKey(&sddl))
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create security descriptor from string.
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CSecurityDesc sd;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!sd.FromString(sddl.c_str()))
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool result = true;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restore DACL and Owner of the key from saved security descriptor.
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CDacl dacl;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CSid owner;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sd.GetDacl(&dacl);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sd.GetOwner(&owner);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD error = ::SetNamedSecurityInfo(const_cast<wchar_t*>(key_name),
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SE_REGISTRY_KEY, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const_cast<SID*>(owner.GetPSID()), NULL,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const_cast<ACL*>(dacl.GetPACL()), NULL);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeleteBackupKey();
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (error == ERROR_SUCCESS);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read SDDL string from backup key
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ReadBackupKey(std::wstring* sddl) {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RegKey backup_key(HKEY_LOCAL_MACHINE, backup_key_name_.c_str(), KEY_READ);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!backup_key.Valid())
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD len = 0;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD reg_type = REG_NONE;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (backup_key.ReadValue(NULL, NULL, &len, &reg_type) != ERROR_SUCCESS)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_EQ(0u, len % sizeof(wchar_t));
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((len == 0) || (reg_type != REG_SZ))
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t wchar_count = 1 + len / sizeof(wchar_t);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (backup_key.ReadValue(NULL, WriteInto(sddl, wchar_count), &len,
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &reg_type) != ERROR_SUCCESS) {
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeleteBackupKey() {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::RegDeleteKey(HKEY_LOCAL_MACHINE, backup_key_name_.c_str());
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring backup_key_name_;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TokenWithPrivileges {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TokenWithPrivileges() {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    token_.GetEffectiveToken(TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    token_.GetUser(&user_);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TokenWithPrivileges() {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    token_.EnableDisablePrivileges(take_ownership_);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    token_.EnableDisablePrivileges(restore_);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool EnablePrivileges() {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (take_ownership_.GetCount() == 0)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!token_.EnablePrivilege(L"SeTakeOwnershipPrivilege",
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  &take_ownership_))
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (restore_.GetCount() == 0)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!token_.EnablePrivilege(L"SeRestorePrivilege", &restore_))
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CSid& GetUser() const {
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return user_;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CAccessToken token_;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CTokenPrivileges take_ownership_;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CTokenPrivileges restore_;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CSid user_;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const wchar_t* const kMimeHandlerKeyValues[] = {
5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  L"ChromeTab.ChromeActiveDocument",
5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  L"ChromeTab.ChromeActiveDocument.1",
5884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Returns true if the values are present or absent in |root_key|'s Secure Mime
5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Handlers key based on |for_installed|. Returns false if the values are not as
5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// expected or if an error occurred.
5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool MimeHandlerKeyIsConfigured(bool for_install, HKEY root_key) {
5944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  string16 key_name(kInternetSettings);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key_name.append(L"\\Secure Mime Handlers");
5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RegKey key(root_key, key_name.c_str(), KEY_QUERY_VALUE);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!key.Valid())
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kMimeHandlerKeyValues); ++i) {
6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DWORD value = 0;
6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LONG result = key.ReadValueDW(kMimeHandlerKeyValues[i], &value);
6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (for_install) {
6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (result != ERROR_SUCCESS || value != 1)
6054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        return false;
6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    } else {
6074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (result != ERROR_FILE_NOT_FOUND)
6084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        return false;
6094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return true;
6124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)HRESULT SetOrDeleteMimeHandlerKey(bool set, HKEY root_key) {
6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  string16 key_name(kInternetSettings);
6164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  key_name.append(L"\\Secure Mime Handlers");
6174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RegKey key(root_key, key_name.c_str(), KEY_SET_VALUE);
6184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!key.Valid())
6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
6204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HRESULT result = S_OK;
6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kMimeHandlerKeyValues); ++i) {
6234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LONG intermediate = set ?
6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        key.WriteValue(kMimeHandlerKeyValues[i], 1) :
6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        key.DeleteValue(kMimeHandlerKeyValues[i]);
6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (intermediate != ERROR_SUCCESS && result == S_OK)
6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      result = HRESULT_FROM_WIN32(intermediate);
6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return result;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OnPinModule() {
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Pin crash reporting by leaking a reference.
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ignore_result(new chrome_frame::ScopedCrashReporting());
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Chrome Frame registration functions.
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RegisterSecuredMimeHandler(bool enable, bool is_system) {
6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (MimeHandlerKeyIsConfigured(enable, HKEY_LOCAL_MACHINE))
6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return S_OK;
6424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!is_system)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SetOrDeleteMimeHandlerKey(enable, HKEY_CURRENT_USER);
6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (base::win::GetVersion() < base::win::VERSION_VISTA)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SetOrDeleteMimeHandlerKey(enable, HKEY_LOCAL_MACHINE);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring mime_key = kInternetSettings;
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mime_key.append(L"\\Secure Mime Handlers");
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring backup_key = kInternetSettings;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backup_key.append(L"\\__backup_SMH__");
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring object_name = L"MACHINE\\";
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  object_name.append(mime_key);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TokenWithPrivileges token_;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!token_.EnablePrivileges())
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_ACCESSDENIED;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there is a backup key - something bad happened; try to restore
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // security on "Secure Mime Handlers" from the backup.
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SecurityDescBackup backup(backup_key);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backup.RestoreSecurity(object_name.c_str());
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read old security descriptor of the Mime key first.
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CSecurityDesc sd;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!AtlGetSecurityDescriptor(object_name.c_str(), SE_REGISTRY_KEY, &sd)) {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_FAIL;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backup.SaveSecurity(sd);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = E_FAIL;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // set new owner
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (AtlSetOwnerSid(object_name.c_str(), SE_REGISTRY_KEY, token_.GetUser())) {
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // set new dacl
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CDacl new_dacl;
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sd.GetDacl(&new_dacl);
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_dacl.AddAllowedAce(token_.GetUser(), GENERIC_WRITE | GENERIC_READ);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (AtlSetDacl(object_name.c_str(), SE_REGISTRY_KEY, new_dacl)) {
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = SetOrDeleteMimeHandlerKey(enable, HKEY_LOCAL_MACHINE);
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backup.RestoreSecurity(object_name.c_str());
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RegisterActiveDoc(bool reg, bool is_system) {
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have to call the static T::UpdateRegistry function instead of
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // _AtlModule.UpdateRegistryFromResourceS(IDR_CHROMEFRAME_ACTIVEDOC, reg)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because there is specific OLEMISC replacement.
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ChromeActiveDocument::UpdateRegistry(reg);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RegisterActiveX(bool reg, bool is_system) {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have to call the static T::UpdateRegistry function instead of
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // _AtlModule.UpdateRegistryFromResourceS(IDR_CHROMEFRAME_ACTIVEX, reg)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because there is specific OLEMISC replacement.
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ChromeFrameActivex::UpdateRegistry(reg);
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RegisterElevationPolicy(bool reg, bool is_system) {
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = S_OK;
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Register the elevation policy. This must succeed for Chrome Frame to
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be able launch Chrome when running in low-integrity IE.
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = _AtlModule.UpdateRegistryFromResourceS(IDR_CHROMEFRAME_ELEVATION, reg);
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr)) {
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Ignore failures since old versions of IE 7 (e.g., 7.0.6000.16386, which
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // shipped with Vista RTM) do not export IERefreshElevationPolicy.
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RefreshElevationPolicy();
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RegisterProtocol(bool reg, bool is_system) {
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _AtlModule.UpdateRegistryFromResourceS(IDR_CHROMEPROTOCOL, reg);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RegisterBhoClsid(bool reg, bool is_system) {
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Bho::UpdateRegistry(reg);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RegisterBhoIE(bool reg, bool is_system) {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_system) {
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return _AtlModule.UpdateRegistryFromResourceS(IDR_REGISTER_BHO, reg);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (reg) {
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Setup the long running process:
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return SetupUserLevelHelper();
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Unschedule the user-level helper. Note that we don't kill it here
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // so that during updates we don't have a time window with no running
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // helper. Uninstalls and updates will explicitly kill the helper from
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // within the installer. Unregister existing run-at-startup entry.
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return base::win::RemoveCommandFromAutoRun(HKEY_CURRENT_USER,
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 kRunKeyName) ? S_OK : E_FAIL;
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RegisterTypeLib(bool reg, bool is_system) {
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (reg && !is_system) {
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Enables the RegisterTypeLib Function function to override default
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // registry mappings under Windows Vista Service Pack 1 (SP1),
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Windows Server 2008, and later operating system versions
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef void (WINAPI* OaEnablePerUserTypeLibReg)(void);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OaEnablePerUserTypeLibReg per_user_typelib_func =
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<OaEnablePerUserTypeLibReg>(
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetProcAddress(GetModuleHandle(L"oleaut32.dll"),
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           "OaEnablePerUserTLibRegistration"));
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (per_user_typelib_func) {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*per_user_typelib_func)();
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reg ?
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UtilRegisterTypeLib(_AtlComModule.m_hInstTypeLib,
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          NULL, !is_system) :
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UtilUnRegisterTypeLib(_AtlComModule.m_hInstTypeLib,
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            NULL, !is_system);
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RegisterLegacyNPAPICleanup(bool reg, bool is_system) {
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reg) {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    _AtlModule.UpdateRegistryFromResourceS(IDR_CHROMEFRAME_NPAPI, reg);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UtilRemovePersistentNPAPIMarker();
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ignore failures.
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RegisterAppId(bool reg, bool is_system) {
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _AtlModule.UpdateRegistryAppId(reg);
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT RegisterUserAgent(bool reg, bool is_system) {
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (reg) {
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SetChromeFrameUA(is_system, L"1");
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SetChromeFrameUA(is_system, NULL);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum RegistrationStepId {
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepSecuredMimeHandler = 0,
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepActiveDoc          = 1,
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepActiveX            = 2,
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepElevationPolicy    = 3,
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepProtocol           = 4,
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepBhoClsid           = 5,
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepBhoRegistration    = 6,
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepRegisterTypeLib    = 7,
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepNpapiCleanup       = 8,
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepAppId              = 9,
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepUserAgent          = 10,
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStepEnd                = 11
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum RegistrationFlags {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ACTIVEX             = 0x0001,
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ACTIVEDOC           = 0x0002,
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GCF_PROTOCOL        = 0x0004,
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BHO_CLSID           = 0x0008,
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BHO_REGISTRATION    = 0x0010,
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TYPELIB             = 0x0020,
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ALL                 = 0xFFFF
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mux the failure step into the hresult. We take only the first four bits
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and stick those into the top four bits of the facility code. We also set the
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Customer bit to be polite. Graphically, we write our error code to the
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bits marked with ^:
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  +---+-+-+-----------------------+-------------------------------+
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  |Sev|C|R|     Facility          |               Code            |
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  +---+-+-+-----------------------+-------------------------------+
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       ^   ^ ^ ^ ^
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://msdn.microsoft.com/en-us/library/cc231198(PROT.10).aspx for
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// more details on HRESULTS.
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The resulting error can be extracted by:
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// error_code = (fiddled_hr & 0x07800000) >> 23
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT MuxErrorIntoHRESULT(HRESULT hr, int error_code) {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(error_code, 0);
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LT(error_code, kStepEnd);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(kStepEnd <= 0xF, update_error_muxing_too_many_steps);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that our four desired bits are clear.
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 0xF87FFFFF == 11111000011111111111111111111111
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(static_cast<HRESULT>(hr & 0xF87FFFFF), hr);
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT fiddled_hr = ((error_code & 0xF) << 23) | hr;
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fiddled_hr |= 1 << 29;  // Set the customer bit.
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return fiddled_hr;
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT CustomRegistration(uint16 reg_flags, bool reg, bool is_system) {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (reg && (reg_flags & (ACTIVEDOC | ACTIVEX)))
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reg_flags |= (TYPELIB | GCF_PROTOCOL);
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the flag that gets checked in AddCommonRGSReplacements before doing
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // registration work.
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  _AtlModule.do_system_registration_ = is_system;
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef HRESULT (*RegistrationFn)(bool reg, bool is_system);
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct RegistrationStep {
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RegistrationStepId id;
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint16 condition;
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RegistrationFn func;
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const RegistrationStep registration_steps[] = {
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kStepSecuredMimeHandler, ACTIVEDOC, &RegisterSecuredMimeHandler },
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kStepActiveDoc, ACTIVEDOC, &RegisterActiveDoc },
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kStepActiveX, ACTIVEX, &RegisterActiveX },
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kStepElevationPolicy, (ACTIVEDOC | ACTIVEX), &RegisterElevationPolicy },
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kStepProtocol, GCF_PROTOCOL, &RegisterProtocol },
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kStepBhoClsid, BHO_CLSID, &RegisterBhoClsid },
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kStepBhoRegistration, BHO_REGISTRATION, &RegisterBhoIE },
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kStepRegisterTypeLib, TYPELIB, &RegisterTypeLib },
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kStepNpapiCleanup, ALL, &RegisterLegacyNPAPICleanup },
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kStepAppId, ALL, &RegisterAppId },
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kStepUserAgent, ALL, &RegisterUserAgent }
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = S_OK;
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rollback = false;
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int failure_step = 0;
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT step_hr = S_OK;
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int step = 0; step < arraysize(registration_steps); ++step) {
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((reg_flags & registration_steps[step].condition) != 0) {
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      step_hr = registration_steps[step].func(reg, is_system);
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (FAILED(step_hr)) {
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Store only the first failing HRESULT with the step value muxed in.
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (hr == S_OK) {
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          hr = MuxErrorIntoHRESULT(step_hr, step);
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // On registration if a step fails, we abort and rollback.
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (reg) {
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          rollback = true;
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          failure_step = step;
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rollback) {
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(reg);
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Rollback the failing action and all preceding ones.
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int step = failure_step; step >= 0; --step) {
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      registration_steps[step].func(!reg, is_system);
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DLL Entry Point
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" BOOL WINAPI DllMain(HINSTANCE instance,
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               DWORD reason,
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               LPVOID reserved) {
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNREFERENCED_PARAMETER(instance);
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (reason == DLL_PROCESS_ATTACH) {
910f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if _ATL_VER < 0x0C00 && !defined(NDEBUG)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Silence traces from the ATL registrar to reduce the log noise.
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ATL::CTrace::s_trace.ChangeCategory(atlTraceRegistrar, 0,
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        ATLTRACESTATUS_DISABLED);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitGoogleUrl();
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_exit_manager = new base::AtExitManager();
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLine::Init(0, NULL);
919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    logging::LoggingSettings settings;
920eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
921eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    logging::InitLogging(settings);
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Log the same items as Chrome.
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logging::SetLogItems(true,  // enable_process_id
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         true,  // enable_thread_id
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         false, // enable_timestamp
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         true); // enable_tickcount
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DllRedirector* dll_redirector = DllRedirector::GetInstance();
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(dll_redirector);
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dll_redirector->RegisterAsFirstCFModule()) {
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Someone else was here first, try and get a pointer to their
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // DllGetClassObject export:
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      g_dll_get_class_object_redir_ptr =
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          dll_redirector->GetDllGetClassObjectPtr();
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(g_dll_get_class_object_redir_ptr != NULL)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "Found CF module with no DllGetClassObject export.";
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Enable trace control and transport through event tracing for Windows.
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logging::LogEventProvider::Initialize(kChromeFrameProvider);
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Set a callback so that crash reporting can be pinned when the module is
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // pinned.
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chrome_frame::SetPinModuleCallback(&OnPinModule);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (reason == DLL_PROCESS_DETACH) {
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DllRedirector* dll_redirector = DllRedirector::GetInstance();
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(dll_redirector);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dll_redirector->UnregisterAsFirstCFModule();
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_patch_helper.UnpatchIfNeeded();
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete g_exit_manager;
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_exit_manager = NULL;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _AtlModule.DllMain(reason, reserved);
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used to determine whether the DLL can be unloaded by OLE
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDAPI DllCanUnloadNow() {
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _AtlModule.DllCanUnloadNow();
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a class factory to create an object of the requested type
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) {
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome_frame::ScopedCrashReporting crash_reporting;
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // IE 11+ are unsupported.
970f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (GetIEVersion() > IE_10) {
971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return CLASS_E_CLASSNOTAVAILABLE;
972f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
973f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we found another module present when we were loaded, then delegate to
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that:
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_dll_get_class_object_redir_ptr) {
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return g_dll_get_class_object_redir_ptr(rclsid, riid, ppv);
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable sniffing and switching only if asked for BHO
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (we use BHO to get loaded in IE).
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rclsid == CLSID_ChromeFrameBHO) {
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_patch_helper.InitializeAndPatchProtocolsIfNeeded();
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DllRegisterServer - Adds entries to the system registry
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDAPI DllRegisterServer() {
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome_frame::ScopedCrashReporting crash_reporting;
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint16 flags =  ACTIVEX | ACTIVEDOC | TYPELIB | GCF_PROTOCOL |
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  BHO_CLSID | BHO_REGISTRATION;
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = CustomRegistration(flags, true, true);
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SUCCEEDED(hr)) {
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetupRunOnce();
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DllUnregisterServer - Removes entries from the system registry
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDAPI DllUnregisterServer() {
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome_frame::ScopedCrashReporting crash_reporting;
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = CustomRegistration(ALL, false, true);
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DllRegisterUserServer - Adds entries to the HKCU hive in the registry.
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDAPI DllRegisterUserServer() {
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome_frame::ScopedCrashReporting crash_reporting;
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UINT flags =  ACTIVEX | ACTIVEDOC | TYPELIB | GCF_PROTOCOL |
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                BHO_CLSID | BHO_REGISTRATION;
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = CustomRegistration(flags, TRUE, false);
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SUCCEEDED(hr)) {
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetupRunOnce();
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DllUnregisterUserServer - Removes entries from the HKCU hive in the registry.
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDAPI DllUnregisterUserServer() {
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome_frame::ScopedCrashReporting crash_reporting;
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = CustomRegistration(ALL, FALSE, false);
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Object entries go here instead of with each object, so that we can move
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the objects to a lib. Also reduces magic.
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OBJECT_ENTRY_AUTO(CLSID_ChromeFrameBHO, Bho)
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OBJECT_ENTRY_AUTO(__uuidof(ChromeActiveDocument), ChromeActiveDocument)
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OBJECT_ENTRY_AUTO(__uuidof(ChromeFrame), ChromeFrameActivex)
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OBJECT_ENTRY_AUTO(__uuidof(ChromeProtocol), ChromeProtocol)
1037