summaryrefslogtreecommitdiffstats
path: root/chrome_frame/chrome_tab.cc
diff options
context:
space:
mode:
authorslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
committerslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
commitf781782dd67077478e117c61dca4ea5eefce3544 (patch)
tree4801f724123cfdcbb69c4e7fe40a565b331723ae /chrome_frame/chrome_tab.cc
parent63cf4759efa2373e33436fb5df6849f930081226 (diff)
downloadchromium_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.cc308
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;
+}