diff options
author | slightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-24 05:11:58 +0000 |
---|---|---|
committer | slightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-24 05:11:58 +0000 |
commit | f781782dd67077478e117c61dca4ea5eefce3544 (patch) | |
tree | 4801f724123cfdcbb69c4e7fe40a565b331723ae /chrome_frame/chrome_tab.cc | |
parent | 63cf4759efa2373e33436fb5df6849f930081226 (diff) | |
download | chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.zip chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.gz chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.bz2 |
Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming in a separate CL.
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/218019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/chrome_tab.cc')
-rw-r--r-- | chrome_frame/chrome_tab.cc | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/chrome_frame/chrome_tab.cc b/chrome_frame/chrome_tab.cc new file mode 100644 index 0000000..1b10ff6 --- /dev/null +++ b/chrome_frame/chrome_tab.cc @@ -0,0 +1,308 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// chrome_tab.cc : Implementation of DLL Exports. +#include "base/at_exit.h" +#include "base/command_line.h" +#include "base/file_util.h" +#include "base/file_version_info.h" +#include "base/logging.h" +#include "base/path_service.h" +#include "base/registry.h" +#include "base/string_piece.h" +#include "base/string_util.h" +#include "base/sys_string_conversions.h" +#include "chrome/common/chrome_constants.h" +#include "grit/chrome_frame_resources.h" +#include "chrome_frame/bho.h" +#include "chrome_frame/chrome_frame_automation.h" +#include "chrome_frame/chrome_launcher.h" +#include "chrome_frame/crash_report.h" +#include "chrome_frame/resource.h" +#include "chrome_frame/utils.h" + +// Include without path to make GYP build see it. +#include "chrome_tab.h" // NOLINT + +static const wchar_t kBhoRegistryPath[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer" + L"\\Browser Helper Objects"; + +const wchar_t kBhoNoLoadExplorerValue[] = L"NoExplorer"; + +class ChromeTabModule + : public AtlPerUserModule<CAtlDllModuleT<ChromeTabModule> > { + public: + typedef AtlPerUserModule<CAtlDllModuleT<ChromeTabModule> > ParentClass; + + DECLARE_LIBID(LIBID_ChromeTabLib) + DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CHROMETAB, + "{FD9B1B31-F4D8-436A-8F4F-D3C2E36733D3}") + + // Override to add our SYSTIME binary value to registry scripts. + // See chrome_frame_activex.rgs for usage. + virtual HRESULT AddCommonRGSReplacements(IRegistrarBase* registrar) throw() { + HRESULT hr = ParentClass::AddCommonRGSReplacements(registrar); + + if (SUCCEEDED(hr)) { + SYSTEMTIME local_time; + ::GetSystemTime(&local_time); + std::string hex(HexEncode(&local_time, sizeof(local_time))); + base::StringPiece sp_hex(hex); + hr = registrar->AddReplacement(L"SYSTIME", + base::SysNativeMBToWide(sp_hex).c_str()); + DCHECK(SUCCEEDED(hr)); + } + + if (SUCCEEDED(hr)) { + std::wstring app_path( + chrome_launcher::GetChromeExecutablePath()); + app_path = file_util::GetDirectoryFromPath(app_path); + hr = registrar->AddReplacement(L"CHROME_APPPATH", app_path.c_str()); + DCHECK(SUCCEEDED(hr)); + } + + if (SUCCEEDED(hr)) { + hr = registrar->AddReplacement(L"CHROME_APPNAME", + chrome::kBrowserProcessExecutableName); + DCHECK(SUCCEEDED(hr)); + + // Fill in VERSION from the VERSIONINFO stored in the DLL's resources. + scoped_ptr<FileVersionInfo> module_version_info( + FileVersionInfo::CreateFileVersionInfoForCurrentModule()); + DCHECK(module_version_info != NULL); + std::wstring file_version(module_version_info->file_version()); + hr = registrar->AddReplacement(L"VERSION", file_version.c_str()); + DCHECK(SUCCEEDED(hr)); + } + + if (SUCCEEDED(hr)) { + // Add the directory of chrome_launcher.exe. This will be the same + // as the directory for the current DLL. + std::wstring module_dir; + FilePath module_path; + if (PathService::Get(base::FILE_MODULE, &module_path)) { + module_dir = module_path.DirName().ToWStringHack(); + } else { + NOTREACHED(); + } + hr = registrar->AddReplacement(L"CHROME_LAUNCHER_APPPATH", + module_dir.c_str()); + DCHECK(SUCCEEDED(hr)); + } + + if (SUCCEEDED(hr)) { + // Add the filename of chrome_launcher.exe + hr = registrar->AddReplacement(L"CHROME_LAUNCHER_APPNAME", + chrome_launcher::kLauncherExeBaseName); + DCHECK(SUCCEEDED(hr)); + } + + return hr; + } +}; + +ChromeTabModule _AtlModule; + +base::AtExitManager* g_exit_manager = NULL; + +// DLL Entry Point +extern "C" BOOL WINAPI DllMain(HINSTANCE instance, + DWORD reason, + LPVOID reserved) { + UNREFERENCED_PARAMETER(instance); + if (reason == DLL_PROCESS_ATTACH) { +#ifndef NDEBUG + // Silence traces from the ATL registrar to reduce the log noise. + ATL::CTrace::s_trace.ChangeCategory(atlTraceRegistrar, 0, + ATLTRACESTATUS_DISABLED); +#endif + InitializeCrashReporting(false, false); + g_exit_manager = new base::AtExitManager(); + CommandLine::Init(0, NULL); + logging::InitLogging(NULL, logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, + logging::LOCK_LOG_FILE, logging::DELETE_OLD_LOG_FILE); + } else if (reason == DLL_PROCESS_DETACH) { + g_patch_helper.UnpatchIfNeeded(); + delete g_exit_manager; + g_exit_manager = NULL; + ShutdownCrashReporting(); + } + return _AtlModule.DllMain(reason, reserved); +} + +#ifdef _MANAGED +#pragma managed(pop) +#endif + +const wchar_t kPostPlatformUAKey[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\" + L"User Agent\\Post Platform"; +const wchar_t kClockUserAgent[] = L"chromeframe"; + +// To delete the clock user agent, set value to NULL. +HRESULT SetClockUserAgent(const wchar_t* value) { + HRESULT hr; + RegKey ua_key; + if (ua_key.Create(HKEY_CURRENT_USER, kPostPlatformUAKey, KEY_WRITE)) { + if (value) { + ua_key.WriteValue(kClockUserAgent, value); + } else { + ua_key.DeleteValue(kClockUserAgent); + } + hr = S_OK; + } else { + DLOG(ERROR) << __FUNCTION__ << ": " << kPostPlatformUAKey; + hr = E_UNEXPECTED; + } + + return hr; +} + +HRESULT RefreshElevationPolicy() { + const wchar_t kIEFrameDll[] = L"ieframe.dll"; + const char kIERefreshPolicy[] = "IERefreshElevationPolicy"; + HRESULT hr = E_NOTIMPL; + HMODULE ieframe_module = LoadLibrary(kIEFrameDll); + if (ieframe_module) { + typedef HRESULT (__stdcall *IERefreshPolicy)(); + IERefreshPolicy ie_refresh_policy = reinterpret_cast<IERefreshPolicy>( + GetProcAddress(ieframe_module, kIERefreshPolicy)); + + if (ie_refresh_policy) { + hr = ie_refresh_policy(); + } else { + hr = HRESULT_FROM_WIN32(GetLastError()); + } + + FreeLibrary(ieframe_module); + } else { + hr = HRESULT_FROM_WIN32(GetLastError()); + } + + return hr; +} + +HRESULT RegisterChromeTabBHO() { + RegKey ie_bho_key; + if (!ie_bho_key.Create(HKEY_LOCAL_MACHINE, kBhoRegistryPath, + KEY_CREATE_SUB_KEY)) { + DLOG(WARNING) << "Failed to open registry key " + << kBhoRegistryPath + << " for write"; + return E_FAIL; + } + + wchar_t bho_class_id_as_string[MAX_PATH] = {0}; + StringFromGUID2(CLSID_ChromeFrameBHO, bho_class_id_as_string, + arraysize(bho_class_id_as_string)); + + if (!ie_bho_key.CreateKey(bho_class_id_as_string, KEY_READ | KEY_WRITE)) { + DLOG(WARNING) << "Failed to create bho registry key under " + << kBhoRegistryPath + << " for write"; + return E_FAIL; + } + + ie_bho_key.WriteValue(kBhoNoLoadExplorerValue, 1); + DLOG(INFO) << "Registered ChromeTab BHO"; + + SetClockUserAgent(L"1"); + RefreshElevationPolicy(); + return S_OK; +} + +HRESULT UnregisterChromeTabBHO() { + SetClockUserAgent(NULL); + + RegKey ie_bho_key; + if (!ie_bho_key.Open(HKEY_LOCAL_MACHINE, kBhoRegistryPath, + KEY_READ | KEY_WRITE)) { + DLOG(WARNING) << "Failed to open registry key " + << kBhoRegistryPath + << " for write."; + return E_FAIL; + } + + wchar_t bho_class_id_as_string[MAX_PATH] = {0}; + StringFromGUID2(CLSID_ChromeFrameBHO, bho_class_id_as_string, + arraysize(bho_class_id_as_string)); + + if (!ie_bho_key.DeleteKey(bho_class_id_as_string)) { + DLOG(WARNING) << "Failed to delete bho registry key " + << bho_class_id_as_string + << " under " + << kBhoRegistryPath; + return E_FAIL; + } + + DLOG(INFO) << "Unregistered ChromeTab BHO"; + return S_OK; +} + +// Used to determine whether the DLL can be unloaded by OLE +STDAPI DllCanUnloadNow() { + return _AtlModule.DllCanUnloadNow(); +} + +// Returns a class factory to create an object of the requested type +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { + if (g_patch_helper.state() == PatchHelper::UNKNOWN) { + g_patch_helper.InitializeAndPatchProtocolsIfNeeded(); + UrlMkSetSessionOption(URLMON_OPTION_USERAGENT_REFRESH, NULL, 0, 0); + } + + return _AtlModule.DllGetClassObject(rclsid, riid, ppv); +} + +// DllRegisterServer - Adds entries to the system registry +STDAPI DllRegisterServer() { + // registers object, typelib and all interfaces in typelib + HRESULT hr = _AtlModule.DllRegisterServer(TRUE); + +#ifdef GOOGLE_CHROME_BUILD + // Muck with the Omaha configuration so that we don't get updated by non-CF + // Google Chrome builds. + UtilUpdateOmahaConfig(true); +#endif + + if (SUCCEEDED(hr)) { + // Best effort attempt to register the BHO. At this point we silently + // ignore any errors during registration. There are some traces emitted + // to the debug log. + RegisterChromeTabBHO(); + } + + return hr; +} + +// DllUnregisterServer - Removes entries from the system registry +STDAPI DllUnregisterServer() { + HRESULT hr = _AtlModule.DllUnregisterServer(TRUE); + +#ifdef GOOGLE_CHROME_BUILD + // Undo any prior mucking with the Omaha config. + UtilUpdateOmahaConfig(false); +#endif + + if (SUCCEEDED(hr)) { + // Best effort attempt to unregister the BHO. At this point we silently + // ignore any errors during unregistration. There are some traces emitted + // to the debug log. + UnregisterChromeTabBHO(); + } + return hr; +} + +STDAPI RegisterNPAPIPlugin() { + HRESULT hr = _AtlModule.UpdateRegistryFromResourceS(IDR_CHROMEFRAME_NPAPI, + TRUE); + return hr; +} + +STDAPI UnregisterNPAPIPlugin() { + HRESULT hr = _AtlModule.UpdateRegistryFromResourceS(IDR_CHROMEFRAME_NPAPI, + FALSE); + return hr; +} |