diff options
author | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-17 04:48:37 +0000 |
---|---|---|
committer | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-17 04:48:37 +0000 |
commit | 3f55e8712f88d8477d9e58f68958e83c92664389 (patch) | |
tree | 21f9eeeda041fd570c31d8b0f266f780b767418f | |
parent | cd1c89e833b7e67b7a7ca8799122e07b65999771 (diff) | |
download | chromium_src-3f55e8712f88d8477d9e58f68958e83c92664389.zip chromium_src-3f55e8712f88d8477d9e58f68958e83c92664389.tar.gz chromium_src-3f55e8712f88d8477d9e58f68958e83c92664389.tar.bz2 |
Add the chromeframe tag to the user agent header at runtime instead of statically in the registry.TEST=Try disabling GCF and see if the chromeframe tag in the user agent is still set. It should not be. Also make sure you don't have an older version installed... the chromeframe tag should not be in the registry - if it is, you've got an older version still registered. This should fix the issue with going to wave.google.com after disabling chrome frame and seeing the white page of death.R=amitBUG=22760
Review URL: http://codereview.chromium.org/259025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29370 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome_frame/bho.cc | 5 | ||||
-rw-r--r-- | chrome_frame/chrome_frame.gyp | 1493 | ||||
-rw-r--r-- | chrome_frame/chrome_tab.cc | 15 | ||||
-rw-r--r-- | chrome_frame/html_utils.cc | 76 | ||||
-rw-r--r-- | chrome_frame/html_utils.h | 24 | ||||
-rw-r--r-- | chrome_frame/http_negotiate.cc | 164 | ||||
-rw-r--r-- | chrome_frame/http_negotiate.h | 47 | ||||
-rw-r--r-- | chrome_frame/protocol_sink_wrap.cc | 52 | ||||
-rw-r--r-- | chrome_frame/protocol_sink_wrap.h | 32 | ||||
-rw-r--r-- | chrome_frame/test/html_util_unittests.cc | 96 | ||||
-rw-r--r-- | chrome_frame/test/http_negotiate_unittest.cc | 118 | ||||
-rw-r--r-- | chrome_frame/utils.h | 62 | ||||
-rw-r--r-- | chrome_frame/vtable_patch_manager.cc | 71 | ||||
-rw-r--r-- | chrome_frame/vtable_patch_manager.h | 62 |
14 files changed, 1500 insertions, 817 deletions
diff --git a/chrome_frame/bho.cc b/chrome_frame/bho.cc index 52d19ba..e83c8ba 100644 --- a/chrome_frame/bho.cc +++ b/chrome_frame/bho.cc @@ -14,6 +14,7 @@ #include "base/scoped_variant_win.h" #include "base/string_util.h" #include "chrome_tab.h" // NOLINT +#include "chrome_frame/http_negotiate.h" #include "chrome_frame/protocol_sink_wrap.h" #include "chrome_frame/utils.h" #include "chrome_frame/vtable_patch_manager.h" @@ -214,6 +215,8 @@ void PatchHelper::InitializeAndPatchProtocolsIfNeeded() { if (state_ != UNKNOWN) return; + HttpNegotiatePatch::Initialize(); + bool patch_protocol = GetConfigBool(true, kPatchProtocols); if (patch_protocol) { ProtocolSinkWrap::PatchProtocolHandlers(); @@ -237,6 +240,8 @@ void PatchHelper::UnpatchIfNeeded() { vtable_patch::UnpatchInterfaceMethods(IBrowserService_PatchInfo); } + HttpNegotiatePatch::Uninitialize(); + state_ = UNKNOWN; } diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp index a84b874..31a3424 100644 --- a/chrome_frame/chrome_frame.gyp +++ b/chrome_frame/chrome_frame.gyp @@ -1,741 +1,752 @@ -# 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.
-
-{
- 'variables': {
- 'chromium_code': 1,
- 'xul_sdk_dir': '../third_party/xulrunner-sdk/<(OS)',
-
- # Keep the archive builder happy.
- 'chrome_personalization%': 1,
- 'use_syncapi_stub%': 0,
-
- # Deps info.
- 'xul_include_directories': [
- # TODO(slightlyoff): pare these down. This makes it too easy to
- # regress to using unfrozen FF interfaces.
- '<(xul_sdk_dir)/include',
- '<(xul_sdk_dir)/include/accessibility',
- '<(xul_sdk_dir)/include/alerts',
- '<(xul_sdk_dir)/include/appcomps',
- '<(xul_sdk_dir)/include/appshell',
- '<(xul_sdk_dir)/include/autocomplete',
- '<(xul_sdk_dir)/include/autoconfig',
- '<(xul_sdk_dir)/include/ax_common',
- '<(xul_sdk_dir)/include/browser',
- '<(xul_sdk_dir)/include/cairo',
- '<(xul_sdk_dir)/include/caps',
- '<(xul_sdk_dir)/include/chardet',
- '<(xul_sdk_dir)/include/chrome',
- '<(xul_sdk_dir)/include/commandhandler',
- '<(xul_sdk_dir)/include/composer',
- '<(xul_sdk_dir)/include/content',
- '<(xul_sdk_dir)/include/contentprefs',
- '<(xul_sdk_dir)/include/cookie',
- '<(xul_sdk_dir)/include/crashreporter',
- '<(xul_sdk_dir)/include/docshell',
- '<(xul_sdk_dir)/include/dom',
- '<(xul_sdk_dir)/include/downloads',
- '<(xul_sdk_dir)/include/editor',
- '<(xul_sdk_dir)/include/embed_base',
- '<(xul_sdk_dir)/include/embedcomponents',
- '<(xul_sdk_dir)/include/expat',
- '<(xul_sdk_dir)/include/extensions',
- '<(xul_sdk_dir)/include/exthandler',
- '<(xul_sdk_dir)/include/exthelper',
- '<(xul_sdk_dir)/include/fastfind',
- '<(xul_sdk_dir)/include/feeds',
- '<(xul_sdk_dir)/include/find',
- '<(xul_sdk_dir)/include/gfx',
- '<(xul_sdk_dir)/include/htmlparser',
- '<(xul_sdk_dir)/include/imgicon',
- '<(xul_sdk_dir)/include/imglib2',
- '<(xul_sdk_dir)/include/inspector',
- '<(xul_sdk_dir)/include/intl',
- '<(xul_sdk_dir)/include/jar',
- '<(xul_sdk_dir)/include/java',
- '<(xul_sdk_dir)/include/jpeg',
- '<(xul_sdk_dir)/include/js',
- '<(xul_sdk_dir)/include/jsdebug',
- '<(xul_sdk_dir)/include/jsurl',
- '<(xul_sdk_dir)/include/layout',
- '<(xul_sdk_dir)/include/lcms',
- '<(xul_sdk_dir)/include/libbz2',
- '<(xul_sdk_dir)/include/libmar',
- '<(xul_sdk_dir)/include/libpixman',
- '<(xul_sdk_dir)/include/libreg',
- '<(xul_sdk_dir)/include/liveconnect',
- '<(xul_sdk_dir)/include/locale',
- '<(xul_sdk_dir)/include/loginmgr',
- '<(xul_sdk_dir)/include/lwbrk',
- '<(xul_sdk_dir)/include/mimetype',
- '<(xul_sdk_dir)/include/morkreader',
- '<(xul_sdk_dir)/include/necko',
- '<(xul_sdk_dir)/include/nkcache',
- '<(xul_sdk_dir)/include/nspr',
- '<(xul_sdk_dir)/include/nss',
- '<(xul_sdk_dir)/include/oji',
- '<(xul_sdk_dir)/include/parentalcontrols',
- '<(xul_sdk_dir)/include/pipboot',
- '<(xul_sdk_dir)/include/pipnss',
- '<(xul_sdk_dir)/include/pippki',
- '<(xul_sdk_dir)/include/places',
- '<(xul_sdk_dir)/include/plugin',
- '<(xul_sdk_dir)/include/png',
- '<(xul_sdk_dir)/include/pref',
- '<(xul_sdk_dir)/include/prefetch',
- '<(xul_sdk_dir)/include/profdirserviceprovider',
- '<(xul_sdk_dir)/include/profile',
- '<(xul_sdk_dir)/include/rdf',
- '<(xul_sdk_dir)/include/rdfutil',
- '<(xul_sdk_dir)/include/satchel',
- '<(xul_sdk_dir)/include/shistory',
- '<(xul_sdk_dir)/include/simple',
- '<(xul_sdk_dir)/include/spellchecker',
- '<(xul_sdk_dir)/include/sqlite3',
- '<(xul_sdk_dir)/include/storage',
- '<(xul_sdk_dir)/include/string',
- '<(xul_sdk_dir)/include/thebes',
- '<(xul_sdk_dir)/include/toolkitcomps',
- '<(xul_sdk_dir)/include/txmgr',
- '<(xul_sdk_dir)/include/txtsvc',
- '<(xul_sdk_dir)/include/uconv',
- '<(xul_sdk_dir)/include/ucvcn',
- '<(xul_sdk_dir)/include/ucvibm',
- '<(xul_sdk_dir)/include/ucvja',
- '<(xul_sdk_dir)/include/ucvko',
- '<(xul_sdk_dir)/include/ucvlatin',
- '<(xul_sdk_dir)/include/ucvmath',
- '<(xul_sdk_dir)/include/ucvtw',
- '<(xul_sdk_dir)/include/ucvtw2',
- '<(xul_sdk_dir)/include/unicharutil',
- '<(xul_sdk_dir)/include/update',
- '<(xul_sdk_dir)/include/uriloader',
- '<(xul_sdk_dir)/include/urlformatter',
- '<(xul_sdk_dir)/include/util',
- '<(xul_sdk_dir)/include/view',
- '<(xul_sdk_dir)/include/webbrowserpersist',
- '<(xul_sdk_dir)/include/webbrwsr',
- '<(xul_sdk_dir)/include/webshell',
- '<(xul_sdk_dir)/include/widget',
- '<(xul_sdk_dir)/include/windowwatcher',
- '<(xul_sdk_dir)/include/xml',
- '<(xul_sdk_dir)/include/xml-rpc',
- '<(xul_sdk_dir)/include/xpcom',
- '<(xul_sdk_dir)/include/xpconnect',
- '<(xul_sdk_dir)/include/xpinstall',
- '<(xul_sdk_dir)/include/xulapp',
- '<(xul_sdk_dir)/include/xuldoc',
- '<(xul_sdk_dir)/include/xulrunner',
- '<(xul_sdk_dir)/include/xultmpl',
- '<(xul_sdk_dir)/include/zipwriter',
- '<(xul_sdk_dir)/include/zlib',
- '<(xul_sdk_dir)/sdk/include',
- ],
- 'conditions': [
- ['OS=="win"', {
- 'python': [
- '<(DEPTH)\\third_party\\python_24\\setup_env.bat && python'
- ],
- }, { # OS != win
- 'python': [
- 'python'
- ],
- }],
- ],
- },
- 'includes': [
- '../build/common.gypi',
- ],
- 'target_defaults': {
- 'dependencies': [
- '../chrome/chrome.gyp:chrome_resources',
- '../chrome/chrome.gyp:chrome_strings',
- '../chrome/chrome.gyp:theme_resources',
- '../skia/skia.gyp:skia',
- '../third_party/npapi/npapi.gyp:npapi',
- ],
- 'include_dirs': [
- # all our own includes are relative to src/
- '..',
- ],
- },
- 'targets': [
- {
- # TODO(slightlyoff): de-win23-ify
- 'target_name': 'xulrunner_sdk',
- 'type': 'none',
- 'conditions': [
- ['OS=="win"', {
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<@(xul_include_directories)',
- ],
- 'libraries': [
- '../third_party/xulrunner-sdk/win/lib/xpcomglue_s.lib',
- '../third_party/xulrunner-sdk/win/lib/xpcom.lib',
- '../third_party/xulrunner-sdk/win/lib/nspr4.lib',
- ],
- },
- },],
- ],
- },
- {
- # build the ICU stubs
- 'target_name': 'icu_stubs',
- 'type': 'static_library',
- 'dependencies': [
- '../base/base.gyp:base',
- ],
- 'sources': [
- 'icu_stubs.cc'
- ],
- },
- {
- # TODO(slightlyoff): de-win32-ify
- #
- # build the base_noicu.lib.
- 'target_name': 'base_noicu',
- 'type': 'none',
- 'dependencies': [
- '../base/base.gyp:base',
- 'icu_stubs',
- ],
- 'actions': [
- {
- 'action_name': 'combine_libs',
- 'msvs_cygwin_shell': 0,
- 'inputs': [
- '<(PRODUCT_DIR)/lib/base.lib',
- '<(PRODUCT_DIR)/lib/icu_stubs.lib',
- ],
- 'outputs': [
- '<(PRODUCT_DIR)/lib/base_noicu.lib',
- ],
- 'action': [
- '<@(python)',
- 'combine_libs.py',
- '-o <(_outputs)',
- '-r (icu_|_icu.obj)',
- '<@(_inputs)'],
- },
- ],
- 'direct_dependent_settings': {
- # linker_settings
- 'libraries': [
- '<(PRODUCT_DIR)/lib/base_noicu.lib',
- ],
- },
- },
- {
- 'target_name': 'chrome_frame_unittests',
- 'type': 'executable',
- 'dependencies': [
- '../build/temp_gyp/googleurl.gyp:googleurl',
- '../chrome/chrome.gyp:common',
- '../chrome/chrome.gyp:utility',
- '../testing/gmock.gyp:gmock',
- '../testing/gtest.gyp:gtest',
- 'base_noicu',
- 'icu_stubs',
- 'chrome_frame_npapi',
- 'chrome_frame_strings',
- 'xulrunner_sdk',
- ],
- 'sources': [
- 'chrome_frame_npapi_unittest.cc',
- 'chrome_frame_unittest_main.cc',
- 'chrome_launcher_unittest.cc',
- 'unittest_precompile.h',
- 'unittest_precompile.cc',
- 'urlmon_upload_data_stream.cc',
- 'urlmon_upload_data_stream_unittest.cc',
- 'chrome_frame_histograms.h',
- 'chrome_frame_histograms.cc',
- ],
- 'include_dirs': [
- # To allow including "chrome_tab.h"
- '<(INTERMEDIATE_DIR)',
- ],
- 'resource_include_dirs': [
- '<(INTERMEDIATE_DIR)',
- ],
- 'conditions': [
- ['OS=="win"', {
- 'msvs_settings': {
- 'VCLinkerTool': {
- 'DelayLoadDLLs': ['xpcom.dll', 'nspr4.dll'],
- },
- },
- 'sources': [
- '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_resources.rc',
- '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_strings.rc',
- ],
- 'dependencies': [
- # TODO(slightlyoff): Get automation targets working on OS X
- '../chrome/chrome.gyp:automation',
- '../chrome/installer/installer.gyp:installer_util',
- '../google_update/google_update.gyp:google_update',
- ]
- }],
- ],
- },
- {
- 'target_name': 'chrome_frame_tests',
- 'type': 'executable',
- 'dependencies': [
- # 'base_noicu',
- '../build/temp_gyp/googleurl.gyp:googleurl',
- '../chrome/chrome.gyp:common',
- '../chrome/chrome.gyp:utility',
- '../testing/gmock.gyp:gmock',
- '../testing/gtest.gyp:gtest',
- '../third_party/libxml/libxml.gyp:libxml',
- '../third_party/libxslt/libxslt.gyp:libxslt',
- 'chrome_frame_strings',
- 'chrome_frame_npapi',
- # 'npchrome_tab',
- 'xulrunner_sdk',
- ],
- 'sources': [
- '../base/test_suite.h',
- 'test/chrome_frame_test_utils.cc',
- 'test/chrome_frame_test_utils.h',
- 'test/chrome_frame_automation_mock.cc',
- 'test/chrome_frame_automation_mock.h',
- 'test/chrome_frame_unittests.cc',
- 'test/chrome_frame_unittests.h',
- 'test/com_message_event_unittest.cc',
- 'test/function_stub_unittest.cc',
- 'test/html_util_unittests.cc',
- 'test/http_server.cc',
- 'test/http_server.h',
- 'test/icu_stubs_unittests.cc',
- 'test/run_all_unittests.cc',
- 'test/test_server.cc',
- 'test/test_server.h',
- 'test/test_server_test.cc',
- 'test/util_unittests.cc',
- 'chrome_frame_automation.cc',
- 'chrome_tab.h',
- 'chrome_tab.idl',
- 'com_message_event.cc',
- 'html_utils.cc',
- 'sync_msg_reply_dispatcher.cc',
- 'sync_msg_reply_dispatcher.h',
- 'test_utils.cc',
- 'test_utils.h',
- 'utils.cc',
- 'utils.h',
- 'chrome_frame_histograms.h',
- 'chrome_frame_histograms.cc',
- ],
- 'include_dirs': [
- '<@(xul_include_directories)',
- '../chrome/third_party/wtl/include',
- # To allow including "chrome_tab.h"
- '<(INTERMEDIATE_DIR)',
- ],
- 'resource_include_dirs': [
- '<(INTERMEDIATE_DIR)',
- ],
- 'conditions': [
- ['OS=="win"', {
- 'msvs_settings': {
- 'VCLinkerTool': {
- 'DelayLoadDLLs': ['xpcom.dll', 'nspr4.dll'],
- },
- },
- 'sources': [
- '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_resources.rc',
- '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_strings.rc',
- ],
- 'dependencies': [
- '../chrome/chrome.gyp:automation',
- '../chrome/installer/installer.gyp:installer_util',
- '../google_update/google_update.gyp:google_update',
- ]
- }],
- ],
- },
- {
- 'target_name': 'chrome_frame_perftests',
- 'type': 'executable',
- 'dependencies': [
- '../base/base.gyp:base_i18n',
- '../base/base.gyp:test_support_base',
- '../build/temp_gyp/googleurl.gyp:googleurl',
- '../chrome/chrome.gyp:common',
- '../chrome/chrome.gyp:utility',
- '../testing/gmock.gyp:gmock',
- '../testing/gtest.gyp:gtest',
- '../third_party/libxml/libxml.gyp:libxml',
- '../third_party/libxslt/libxslt.gyp:libxslt',
- 'chrome_frame_strings',
- 'xulrunner_sdk',
- ],
- 'sources': [
- '../base/perf_test_suite.h',
- '../base/perftimer.cc',
- '../base/test/test_file_util.h',
- '../chrome/test/chrome_process_util.cc',
- '../chrome/test/chrome_process_util.h',
- '../chrome/test/ui/ui_test.cc',
- 'chrome_tab.h',
- 'chrome_tab.idl',
- 'html_utils.cc',
- 'test/perf/chrome_frame_perftest.cc',
- 'test/perf/chrome_frame_perftest.h',
- 'test/perf/run_all.cc',
- 'test/perf/silverlight.cc',
- 'test_utils.cc',
- 'test_utils.h',
- 'utils.cc',
- 'utils.h',
- ],
- 'include_dirs': [
- '<@(xul_include_directories)',
- '../chrome/third_party/wtl/include',
- # To allow including "chrome_tab.h"
- '<(INTERMEDIATE_DIR)',
- ],
- 'conditions': [
- ['OS=="win"', {
- 'dependencies': [
- '../chrome/chrome.gyp:automation',
- '../breakpad/breakpad.gyp:breakpad_handler',
- '../chrome/installer/installer.gyp:installer_util',
- '../google_update/google_update.gyp:google_update',
- '../chrome/installer/installer.gyp:installer_util',
- ],
- 'sources': [
- '../chrome/test/perf/mem_usage_win.cc',
- '../chrome/test/chrome_process_util_win.cc',
- '../base/test/test_file_util_win.cc',
- ]
- }],
- ],
- },
-
- {
- 'target_name': 'chrome_frame_net_tests',
- 'type': 'executable',
- 'dependencies': [
- '../base/base.gyp:test_support_base',
- '../chrome/chrome.gyp:browser',
- '../chrome/chrome.gyp:chrome_dll_version',
- '../chrome/chrome.gyp:chrome_resources',
- '../chrome/chrome.gyp:debugger',
- '../chrome/chrome.gyp:renderer',
- '../chrome/chrome.gyp:syncapi',
- '../skia/skia.gyp:skia',
- '../testing/gtest.gyp:gtest',
- '../third_party/icu/icu.gyp:icui18n',
- '../third_party/icu/icu.gyp:icuuc',
- 'chrome_frame_npapi',
- ],
- 'sources': [
- '../net/url_request/url_request_unittest.cc',
- '../net/url_request/url_request_unittest.h',
- 'test/chrome_frame_test_utils.cc',
- 'test/chrome_frame_test_utils.h',
- 'test/test_server.cc',
- 'test/test_server.h',
- 'test/net/dialog_watchdog.cc',
- 'test/net/dialog_watchdog.h',
- 'test/net/fake_external_tab.cc',
- 'test/net/fake_external_tab.h',
- 'test/net/process_singleton_subclass.cc',
- 'test/net/process_singleton_subclass.h',
- 'test/net/test_automation_provider.cc',
- 'test/net/test_automation_provider.h',
- 'test/net/test_automation_resource_message_filter.cc',
- 'test/net/test_automation_resource_message_filter.h',
- ],
- 'include_dirs': [
- # To allow including "chrome_tab.h"
- '<(INTERMEDIATE_DIR)',
- ],
- 'conditions': [
- ['OS=="win"', {
- 'dependencies': [
- '../chrome/chrome.gyp:automation',
- '../breakpad/breakpad.gyp:breakpad_handler',
- '../chrome/installer/installer.gyp:installer_util',
- '../google_update/google_update.gyp:google_update',
- '../chrome/installer/installer.gyp:installer_util',
- ]
- }],
- ],
- },
-
- {
- 'target_name': 'chrome_frame_npapi',
- 'type': 'static_library',
- 'dependencies': [
- 'chrome_frame_strings',
- '../chrome/chrome.gyp:common',
- 'xulrunner_sdk',
- ],
- 'sources': [
- 'chrome_frame_automation.cc',
- 'chrome_frame_automation.h',
- 'chrome_frame_delegate.cc',
- 'chrome_frame_delegate.h',
- 'chrome_frame_plugin.h',
- 'chrome_frame_npapi.cc',
- 'chrome_frame_npapi.h',
- 'chrome_launcher.cc',
- 'chrome_launcher.h',
- 'html_utils.cc',
- 'html_utils.h',
- 'np_browser_functions.cc',
- 'np_browser_functions.h',
- 'np_event_listener.cc',
- 'np_event_listener.h',
- 'np_proxy_service.cc',
- 'np_proxy_service.h',
- 'npapi_url_request.cc',
- 'npapi_url_request.h',
- 'ns_associate_iid_win.h',
- 'ns_isupports_impl.h',
- 'plugin_url_request.cc',
- 'plugin_url_request.h',
- 'scoped_ns_ptr_win.h',
- 'sync_msg_reply_dispatcher.cc',
- 'sync_msg_reply_dispatcher.h',
- 'utils.cc',
- 'utils.h',
- ],
- },
- {
- 'target_name': 'chrome_launcher',
- 'type': 'executable',
- 'msvs_guid': 'B7E540C1-49D9-4350-ACBC-FB8306316D16',
- 'dependencies': [],
- 'sources': [
- 'chrome_launcher_main.cc',
- ],
- 'msvs_settings': {
- 'VCLinkerTool': {
- 'OutputFile':
- '..\\chrome\\$(ConfigurationName)\\servers\\$(ProjectName).exe',
- # Set /SUBSYSTEM:WINDOWS since this is not a command-line program.
- 'SubSystem': '2',
- # We're going for minimal size, so no standard library (in release
- # builds).
- 'IgnoreAllDefaultLibraries': "true",
- },
- 'VCCLCompilerTool': {
- # Requires standard library, so disable it.
- 'BufferSecurityCheck': "false",
- },
- },
- 'configurations': {
- # Bring back the standard library in debug buidls.
- 'Debug': {
- 'msvs_settings': {
- 'VCLinkerTool': {
- 'IgnoreAllDefaultLibraries': "false",
- },
- },
- },
- },
- },
- {
- 'target_name': 'chrome_frame_strings',
- 'type': 'none',
- 'rules': [
- {
- 'rule_name': 'grit',
- 'extension': 'grd',
- 'inputs': [
- '../tools/grit/grit.py',
- ],
- 'variables': {
- 'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/chrome_frame',
- },
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/grit/<(RULE_INPUT_ROOT).h',
- '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/<(RULE_INPUT_ROOT).pak',
- ],
- 'action': ['python', '<@(_inputs)', '-i',
- '<(RULE_INPUT_PATH)',
- 'build', '-o', '<(grit_out_dir)'
- ],
- 'message': 'Generating resources from <(RULE_INPUT_PATH)',
- },
- ],
- 'sources': [
- # Localizable resources.
- 'resources/chrome_frame_strings.grd',
- 'resources/chrome_frame_resources.grd',
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)/chrome_frame',
- ],
- },
- 'conditions': [
- ['OS=="win"', {
- 'dependencies': ['../build/win/system.gyp:cygwin'],
- }],
- ],
- },
- {
- 'target_name': 'npchrome_tab',
- 'type': 'shared_library',
- 'msvs_guid': 'E3DE7E63-D3B6-4A9F-BCC4-5C8169E9C9F2',
- 'dependencies': [
- 'base_noicu',
- 'chrome_frame_npapi',
- 'chrome_frame_strings',
- 'chrome_launcher',
- 'xulrunner_sdk',
- '../chrome/chrome.gyp:common',
- '../chrome/chrome.gyp:utility',
- '../build/temp_gyp/googleurl.gyp:googleurl',
- # FIXME(slightlyoff):
- # gigantic hack to get these to build from main Chrome sln.
- 'chrome_frame_perftests',
- 'chrome_frame_tests',
- 'chrome_frame_unittests',
- 'chrome_frame_net_tests',
- ],
- 'sources': [
- 'bho.cc',
- 'bho.h',
- 'bho.rgs',
- 'chrome_active_document.cc',
- 'chrome_active_document.h',
- 'chrome_active_document.rgs',
- 'chrome_frame_activex.cc',
- 'chrome_frame_activex.h',
- 'chrome_frame_activex_base.h',
- 'chrome_frame_activex.rgs',
- 'chrome_frame_npapi.rgs',
- 'chrome_frame_npapi_entrypoints.cc',
- 'chrome_frame_reporting.cc',
- 'chrome_frame_reporting.h',
- 'chrome_protocol.cc',
- 'chrome_protocol.h',
- 'chrome_protocol.rgs',
- 'chrome_tab.cc',
- 'chrome_tab.def',
- 'chrome_tab.h',
- 'chrome_tab.idl',
- # FIXME(slightlyoff): For chrome_tab.tlb. Giant hack until we can
- # figure out something more gyp-ish.
- 'resources/tlb_resource.rc',
- 'chrome_tab.rgs',
- 'chrome_tab_version.rc.version',
- 'com_message_event.cc',
- 'com_message_event.h',
- 'com_type_info_holder.cc',
- 'com_type_info_holder.h',
- 'ff_30_privilege_check.cc',
- 'ff_privilege_check.h',
- 'find_dialog.cc',
- 'find_dialog.h',
- 'function_stub.h',
- 'icu_stubs.cc',
- 'iids.cc',
- 'in_place_menu.h',
- 'ole_document_impl.h',
- 'protocol_sink_wrap.cc',
- 'protocol_sink_wrap.h',
- 'resource.h',
- 'script_security_manager.h',
- 'sync_msg_reply_dispatcher.cc',
- 'sync_msg_reply_dispatcher.h',
- 'extra_system_apis.h',
- 'urlmon_url_request.cc',
- 'urlmon_url_request.h',
- 'urlmon_upload_data_stream.cc',
- 'urlmon_upload_data_stream.h',
- 'vtable_patch_manager.cc',
- 'vtable_patch_manager.h',
- 'chrome_frame_histograms.h',
- 'chrome_frame_histograms.cc',
- ],
- 'include_dirs': [
- # To allow including "chrome_tab.h"
- '<(INTERMEDIATE_DIR)',
- '<(INTERMEDIATE_DIR)/../npchrome_tab',
- ],
- 'conditions': [
- ['OS=="win"', {
- # NOTE(slightlyoff):
- # this is a fix for the include dirs length limit on the resource
- # compiler, tickled by the xul_include_dirs variable
- 'resource_include_dirs': [
- '<(INTERMEDIATE_DIR)'
- ],
- 'sources': [
- '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_resources.rc',
- '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_strings.rc',
- ],
- 'dependencies': [
- '../breakpad/breakpad.gyp:breakpad_handler',
- '../chrome/chrome.gyp:automation',
- # Make the archive build happy.
- '../chrome/chrome.gyp:syncapi',
- # Installer
- '../chrome/installer/installer.gyp:installer_util',
- '../google_update/google_update.gyp:google_update',
- # Crash Reporting
- 'crash_reporting/crash_reporting.gyp:crash_report',
- ],
- 'msvs_settings': {
- 'VCLinkerTool': {
- 'OutputFile':
- '..\\chrome\\$(ConfigurationName)\\servers\\$(ProjectName).dll',
- 'DelayLoadDLLs': ['xpcom.dll', 'nspr4.dll'],
- 'BaseAddress': '0x33000000',
- # Set /SUBSYSTEM:WINDOWS (for consistency).
- 'SubSystem': '2',
- },
- },
- }],
- ],
- 'rules': [
- # Borrowed from chrome.gyp:chrome_dll_version, branding references
- # removed
- {
- 'rule_name': 'version',
- 'extension': 'version',
- 'variables': {
- 'version_py': '../chrome/tools/build/version.py',
- 'version_path': '../chrome/VERSION',
- 'template_input_path': 'chrome_tab_version.rc.version',
- },
- 'inputs': [
- '<(template_input_path)',
- '<(version_path)',
- ],
- 'outputs': [
- 'chrome_tab_version.rc',
- ],
- 'action': [
- 'python',
- '<(version_py)',
- '-f', '<(version_path)',
- '<(template_input_path)',
- '<@(_outputs)',
- ],
- 'process_outputs_as_sources': 1,
- 'message': 'Generating version information in <(_outputs)'
- },
- ],
- },
- ],
-}
-
-# vim: shiftwidth=2:et:ai:tabstop=2
-
-# Local Variables:
-# tab-width:2
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=2 shiftwidth=2:
+# 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. + +{ + 'variables': { + 'chromium_code': 1, + 'xul_sdk_dir': '../third_party/xulrunner-sdk/<(OS)', + + # Keep the archive builder happy. + 'chrome_personalization%': 1, + 'use_syncapi_stub%': 0, + + # Deps info. + 'xul_include_directories': [ + # TODO(slightlyoff): pare these down. This makes it too easy to + # regress to using unfrozen FF interfaces. + '<(xul_sdk_dir)/include', + '<(xul_sdk_dir)/include/accessibility', + '<(xul_sdk_dir)/include/alerts', + '<(xul_sdk_dir)/include/appcomps', + '<(xul_sdk_dir)/include/appshell', + '<(xul_sdk_dir)/include/autocomplete', + '<(xul_sdk_dir)/include/autoconfig', + '<(xul_sdk_dir)/include/ax_common', + '<(xul_sdk_dir)/include/browser', + '<(xul_sdk_dir)/include/cairo', + '<(xul_sdk_dir)/include/caps', + '<(xul_sdk_dir)/include/chardet', + '<(xul_sdk_dir)/include/chrome', + '<(xul_sdk_dir)/include/commandhandler', + '<(xul_sdk_dir)/include/composer', + '<(xul_sdk_dir)/include/content', + '<(xul_sdk_dir)/include/contentprefs', + '<(xul_sdk_dir)/include/cookie', + '<(xul_sdk_dir)/include/crashreporter', + '<(xul_sdk_dir)/include/docshell', + '<(xul_sdk_dir)/include/dom', + '<(xul_sdk_dir)/include/downloads', + '<(xul_sdk_dir)/include/editor', + '<(xul_sdk_dir)/include/embed_base', + '<(xul_sdk_dir)/include/embedcomponents', + '<(xul_sdk_dir)/include/expat', + '<(xul_sdk_dir)/include/extensions', + '<(xul_sdk_dir)/include/exthandler', + '<(xul_sdk_dir)/include/exthelper', + '<(xul_sdk_dir)/include/fastfind', + '<(xul_sdk_dir)/include/feeds', + '<(xul_sdk_dir)/include/find', + '<(xul_sdk_dir)/include/gfx', + '<(xul_sdk_dir)/include/htmlparser', + '<(xul_sdk_dir)/include/imgicon', + '<(xul_sdk_dir)/include/imglib2', + '<(xul_sdk_dir)/include/inspector', + '<(xul_sdk_dir)/include/intl', + '<(xul_sdk_dir)/include/jar', + '<(xul_sdk_dir)/include/java', + '<(xul_sdk_dir)/include/jpeg', + '<(xul_sdk_dir)/include/js', + '<(xul_sdk_dir)/include/jsdebug', + '<(xul_sdk_dir)/include/jsurl', + '<(xul_sdk_dir)/include/layout', + '<(xul_sdk_dir)/include/lcms', + '<(xul_sdk_dir)/include/libbz2', + '<(xul_sdk_dir)/include/libmar', + '<(xul_sdk_dir)/include/libpixman', + '<(xul_sdk_dir)/include/libreg', + '<(xul_sdk_dir)/include/liveconnect', + '<(xul_sdk_dir)/include/locale', + '<(xul_sdk_dir)/include/loginmgr', + '<(xul_sdk_dir)/include/lwbrk', + '<(xul_sdk_dir)/include/mimetype', + '<(xul_sdk_dir)/include/morkreader', + '<(xul_sdk_dir)/include/necko', + '<(xul_sdk_dir)/include/nkcache', + '<(xul_sdk_dir)/include/nspr', + '<(xul_sdk_dir)/include/nss', + '<(xul_sdk_dir)/include/oji', + '<(xul_sdk_dir)/include/parentalcontrols', + '<(xul_sdk_dir)/include/pipboot', + '<(xul_sdk_dir)/include/pipnss', + '<(xul_sdk_dir)/include/pippki', + '<(xul_sdk_dir)/include/places', + '<(xul_sdk_dir)/include/plugin', + '<(xul_sdk_dir)/include/png', + '<(xul_sdk_dir)/include/pref', + '<(xul_sdk_dir)/include/prefetch', + '<(xul_sdk_dir)/include/profdirserviceprovider', + '<(xul_sdk_dir)/include/profile', + '<(xul_sdk_dir)/include/rdf', + '<(xul_sdk_dir)/include/rdfutil', + '<(xul_sdk_dir)/include/satchel', + '<(xul_sdk_dir)/include/shistory', + '<(xul_sdk_dir)/include/simple', + '<(xul_sdk_dir)/include/spellchecker', + '<(xul_sdk_dir)/include/sqlite3', + '<(xul_sdk_dir)/include/storage', + '<(xul_sdk_dir)/include/string', + '<(xul_sdk_dir)/include/thebes', + '<(xul_sdk_dir)/include/toolkitcomps', + '<(xul_sdk_dir)/include/txmgr', + '<(xul_sdk_dir)/include/txtsvc', + '<(xul_sdk_dir)/include/uconv', + '<(xul_sdk_dir)/include/ucvcn', + '<(xul_sdk_dir)/include/ucvibm', + '<(xul_sdk_dir)/include/ucvja', + '<(xul_sdk_dir)/include/ucvko', + '<(xul_sdk_dir)/include/ucvlatin', + '<(xul_sdk_dir)/include/ucvmath', + '<(xul_sdk_dir)/include/ucvtw', + '<(xul_sdk_dir)/include/ucvtw2', + '<(xul_sdk_dir)/include/unicharutil', + '<(xul_sdk_dir)/include/update', + '<(xul_sdk_dir)/include/uriloader', + '<(xul_sdk_dir)/include/urlformatter', + '<(xul_sdk_dir)/include/util', + '<(xul_sdk_dir)/include/view', + '<(xul_sdk_dir)/include/webbrowserpersist', + '<(xul_sdk_dir)/include/webbrwsr', + '<(xul_sdk_dir)/include/webshell', + '<(xul_sdk_dir)/include/widget', + '<(xul_sdk_dir)/include/windowwatcher', + '<(xul_sdk_dir)/include/xml', + '<(xul_sdk_dir)/include/xml-rpc', + '<(xul_sdk_dir)/include/xpcom', + '<(xul_sdk_dir)/include/xpconnect', + '<(xul_sdk_dir)/include/xpinstall', + '<(xul_sdk_dir)/include/xulapp', + '<(xul_sdk_dir)/include/xuldoc', + '<(xul_sdk_dir)/include/xulrunner', + '<(xul_sdk_dir)/include/xultmpl', + '<(xul_sdk_dir)/include/zipwriter', + '<(xul_sdk_dir)/include/zlib', + '<(xul_sdk_dir)/sdk/include', + ], + 'conditions': [ + ['OS=="win"', { + 'python': [ + '<(DEPTH)\\third_party\\python_24\\setup_env.bat && python' + ], + }, { # OS != win + 'python': [ + 'python' + ], + }], + ], + }, + 'includes': [ + '../build/common.gypi', + ], + 'target_defaults': { + 'dependencies': [ + '../chrome/chrome.gyp:chrome_resources', + '../chrome/chrome.gyp:chrome_strings', + '../chrome/chrome.gyp:theme_resources', + '../skia/skia.gyp:skia', + '../third_party/npapi/npapi.gyp:npapi', + ], + 'include_dirs': [ + # all our own includes are relative to src/ + '..', + ], + }, + 'targets': [ + { + # TODO(slightlyoff): de-win23-ify + 'target_name': 'xulrunner_sdk', + 'type': 'none', + 'conditions': [ + ['OS=="win"', { + 'direct_dependent_settings': { + 'include_dirs': [ + '<@(xul_include_directories)', + ], + 'libraries': [ + '../third_party/xulrunner-sdk/win/lib/xpcomglue_s.lib', + '../third_party/xulrunner-sdk/win/lib/xpcom.lib', + '../third_party/xulrunner-sdk/win/lib/nspr4.lib', + ], + }, + },], + ], + }, + { + # build the ICU stubs + 'target_name': 'icu_stubs', + 'type': 'static_library', + 'dependencies': [ + '../base/base.gyp:base', + ], + 'sources': [ + 'icu_stubs.cc' + ], + }, + { + # TODO(slightlyoff): de-win32-ify + # + # build the base_noicu.lib. + 'target_name': 'base_noicu', + 'type': 'none', + 'dependencies': [ + '../base/base.gyp:base', + 'icu_stubs', + ], + 'actions': [ + { + 'action_name': 'combine_libs', + 'msvs_cygwin_shell': 0, + 'inputs': [ + '<(PRODUCT_DIR)/lib/base.lib', + '<(PRODUCT_DIR)/lib/icu_stubs.lib', + ], + 'outputs': [ + '<(PRODUCT_DIR)/lib/base_noicu.lib', + ], + 'action': [ + '<@(python)', + 'combine_libs.py', + '-o <(_outputs)', + '-r (icu_|_icu.obj)', + '<@(_inputs)'], + }, + ], + 'direct_dependent_settings': { + # linker_settings + 'libraries': [ + '<(PRODUCT_DIR)/lib/base_noicu.lib', + ], + }, + }, + { + 'target_name': 'chrome_frame_unittests', + 'type': 'executable', + 'dependencies': [ + '../build/temp_gyp/googleurl.gyp:googleurl', + '../chrome/chrome.gyp:common', + '../chrome/chrome.gyp:utility', + '../testing/gmock.gyp:gmock', + '../testing/gtest.gyp:gtest', + 'base_noicu', + 'icu_stubs', + 'chrome_frame_npapi', + 'chrome_frame_strings', + 'xulrunner_sdk', + ], + 'sources': [ + 'chrome_frame_npapi_unittest.cc', + 'chrome_frame_unittest_main.cc', + 'chrome_launcher_unittest.cc', + 'unittest_precompile.h', + 'unittest_precompile.cc', + 'urlmon_upload_data_stream.cc', + 'urlmon_upload_data_stream_unittest.cc', + 'chrome_frame_histograms.h', + 'chrome_frame_histograms.cc', + ], + 'include_dirs': [ + # To allow including "chrome_tab.h" + '<(INTERMEDIATE_DIR)', + ], + 'resource_include_dirs': [ + '<(INTERMEDIATE_DIR)', + ], + 'conditions': [ + ['OS=="win"', { + 'msvs_settings': { + 'VCLinkerTool': { + 'DelayLoadDLLs': ['xpcom.dll', 'nspr4.dll'], + }, + }, + 'sources': [ + '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_resources.rc', + '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_strings.rc', + ], + 'dependencies': [ + # TODO(slightlyoff): Get automation targets working on OS X + '../chrome/chrome.gyp:automation', + '../chrome/installer/installer.gyp:installer_util', + '../google_update/google_update.gyp:google_update', + ] + }], + ], + }, + { + 'target_name': 'chrome_frame_tests', + 'type': 'executable', + 'dependencies': [ + # 'base_noicu', + '../build/temp_gyp/googleurl.gyp:googleurl', + '../chrome/chrome.gyp:common', + '../chrome/chrome.gyp:utility', + '../testing/gmock.gyp:gmock', + '../testing/gtest.gyp:gtest', + '../third_party/libxml/libxml.gyp:libxml', + '../third_party/libxslt/libxslt.gyp:libxslt', + 'chrome_frame_strings', + 'chrome_frame_npapi', + # 'npchrome_tab', + 'xulrunner_sdk', + ], + 'sources': [ + '../base/test_suite.h', + 'test/chrome_frame_test_utils.cc', + 'test/chrome_frame_test_utils.h', + 'test/chrome_frame_automation_mock.cc', + 'test/chrome_frame_automation_mock.h', + 'test/chrome_frame_unittests.cc', + 'test/chrome_frame_unittests.h', + 'test/com_message_event_unittest.cc', + 'test/function_stub_unittest.cc', + 'test/html_util_unittests.cc', + 'test/http_negotiate_unittest.cc', + 'test/http_server.cc', + 'test/http_server.h', + 'test/icu_stubs_unittests.cc', + 'test/run_all_unittests.cc', + 'test/test_server.cc', + 'test/test_server.h', + 'test/test_server_test.cc', + 'test/util_unittests.cc', + 'chrome_frame_automation.cc', + 'chrome_frame_histograms.h', + 'chrome_frame_histograms.cc', + 'chrome_tab.h', + 'chrome_tab.idl', + 'com_message_event.cc', + 'html_utils.cc', + 'http_negotiate.h', + 'http_negotiate.cc', + 'sync_msg_reply_dispatcher.cc', + 'sync_msg_reply_dispatcher.h', + 'test_utils.cc', + 'test_utils.h', + 'urlmon_upload_data_stream.h', + 'urlmon_upload_data_stream.cc', + 'urlmon_url_request.h', + 'urlmon_url_request.cc', + 'utils.cc', + 'utils.h', + 'vtable_patch_manager.h', + 'vtable_patch_manager.cc' + ], + 'include_dirs': [ + '<@(xul_include_directories)', + '../chrome/third_party/wtl/include', + # To allow including "chrome_tab.h" + '<(INTERMEDIATE_DIR)', + ], + 'resource_include_dirs': [ + '<(INTERMEDIATE_DIR)', + ], + 'conditions': [ + ['OS=="win"', { + 'msvs_settings': { + 'VCLinkerTool': { + 'DelayLoadDLLs': ['xpcom.dll', 'nspr4.dll'], + }, + }, + 'sources': [ + '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_resources.rc', + '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_strings.rc', + ], + 'dependencies': [ + '../chrome/chrome.gyp:automation', + '../chrome/installer/installer.gyp:installer_util', + '../google_update/google_update.gyp:google_update', + ] + }], + ], + }, + { + 'target_name': 'chrome_frame_perftests', + 'type': 'executable', + 'dependencies': [ + '../base/base.gyp:base_i18n', + '../base/base.gyp:test_support_base', + '../build/temp_gyp/googleurl.gyp:googleurl', + '../chrome/chrome.gyp:common', + '../chrome/chrome.gyp:utility', + '../testing/gmock.gyp:gmock', + '../testing/gtest.gyp:gtest', + '../third_party/libxml/libxml.gyp:libxml', + '../third_party/libxslt/libxslt.gyp:libxslt', + 'chrome_frame_strings', + 'xulrunner_sdk', + ], + 'sources': [ + '../base/perf_test_suite.h', + '../base/perftimer.cc', + '../base/test/test_file_util.h', + '../chrome/test/chrome_process_util.cc', + '../chrome/test/chrome_process_util.h', + '../chrome/test/ui/ui_test.cc', + 'chrome_tab.h', + 'chrome_tab.idl', + 'html_utils.cc', + 'test/perf/chrome_frame_perftest.cc', + 'test/perf/chrome_frame_perftest.h', + 'test/perf/run_all.cc', + 'test/perf/silverlight.cc', + 'test_utils.cc', + 'test_utils.h', + 'utils.cc', + 'utils.h', + ], + 'include_dirs': [ + '<@(xul_include_directories)', + '../chrome/third_party/wtl/include', + # To allow including "chrome_tab.h" + '<(INTERMEDIATE_DIR)', + ], + 'conditions': [ + ['OS=="win"', { + 'dependencies': [ + '../chrome/chrome.gyp:automation', + '../breakpad/breakpad.gyp:breakpad_handler', + '../chrome/installer/installer.gyp:installer_util', + '../google_update/google_update.gyp:google_update', + '../chrome/installer/installer.gyp:installer_util', + ], + 'sources': [ + '../chrome/test/perf/mem_usage_win.cc', + '../chrome/test/chrome_process_util_win.cc', + '../base/test/test_file_util_win.cc', + ] + }], + ], + }, + + { + 'target_name': 'chrome_frame_net_tests', + 'type': 'executable', + 'dependencies': [ + '../base/base.gyp:test_support_base', + '../chrome/chrome.gyp:browser', + '../chrome/chrome.gyp:chrome_dll_version', + '../chrome/chrome.gyp:chrome_resources', + '../chrome/chrome.gyp:debugger', + '../chrome/chrome.gyp:renderer', + '../chrome/chrome.gyp:syncapi', + '../skia/skia.gyp:skia', + '../testing/gtest.gyp:gtest', + '../third_party/icu/icu.gyp:icui18n', + '../third_party/icu/icu.gyp:icuuc', + 'chrome_frame_npapi', + ], + 'sources': [ + '../net/url_request/url_request_unittest.cc', + '../net/url_request/url_request_unittest.h', + 'test/chrome_frame_test_utils.cc', + 'test/chrome_frame_test_utils.h', + 'test/test_server.cc', + 'test/test_server.h', + 'test/net/dialog_watchdog.cc', + 'test/net/dialog_watchdog.h', + 'test/net/fake_external_tab.cc', + 'test/net/fake_external_tab.h', + 'test/net/process_singleton_subclass.cc', + 'test/net/process_singleton_subclass.h', + 'test/net/test_automation_provider.cc', + 'test/net/test_automation_provider.h', + 'test/net/test_automation_resource_message_filter.cc', + 'test/net/test_automation_resource_message_filter.h', + ], + 'include_dirs': [ + # To allow including "chrome_tab.h" + '<(INTERMEDIATE_DIR)', + ], + 'conditions': [ + ['OS=="win"', { + 'dependencies': [ + '../chrome/chrome.gyp:automation', + '../breakpad/breakpad.gyp:breakpad_handler', + '../chrome/installer/installer.gyp:installer_util', + '../google_update/google_update.gyp:google_update', + '../chrome/installer/installer.gyp:installer_util', + ] + }], + ], + }, + + { + 'target_name': 'chrome_frame_npapi', + 'type': 'static_library', + 'dependencies': [ + 'chrome_frame_strings', + '../chrome/chrome.gyp:common', + 'xulrunner_sdk', + ], + 'sources': [ + 'chrome_frame_automation.cc', + 'chrome_frame_automation.h', + 'chrome_frame_delegate.cc', + 'chrome_frame_delegate.h', + 'chrome_frame_plugin.h', + 'chrome_frame_npapi.cc', + 'chrome_frame_npapi.h', + 'chrome_launcher.cc', + 'chrome_launcher.h', + 'html_utils.cc', + 'html_utils.h', + 'np_browser_functions.cc', + 'np_browser_functions.h', + 'np_event_listener.cc', + 'np_event_listener.h', + 'np_proxy_service.cc', + 'np_proxy_service.h', + 'npapi_url_request.cc', + 'npapi_url_request.h', + 'ns_associate_iid_win.h', + 'ns_isupports_impl.h', + 'plugin_url_request.cc', + 'plugin_url_request.h', + 'scoped_ns_ptr_win.h', + 'sync_msg_reply_dispatcher.cc', + 'sync_msg_reply_dispatcher.h', + 'utils.cc', + 'utils.h', + ], + }, + { + 'target_name': 'chrome_launcher', + 'type': 'executable', + 'msvs_guid': 'B7E540C1-49D9-4350-ACBC-FB8306316D16', + 'dependencies': [], + 'sources': [ + 'chrome_launcher_main.cc', + ], + 'msvs_settings': { + 'VCLinkerTool': { + 'OutputFile': + '..\\chrome\\$(ConfigurationName)\\servers\\$(ProjectName).exe', + # Set /SUBSYSTEM:WINDOWS since this is not a command-line program. + 'SubSystem': '2', + # We're going for minimal size, so no standard library (in release + # builds). + 'IgnoreAllDefaultLibraries': "true", + }, + 'VCCLCompilerTool': { + # Requires standard library, so disable it. + 'BufferSecurityCheck': "false", + }, + }, + 'configurations': { + # Bring back the standard library in debug buidls. + 'Debug': { + 'msvs_settings': { + 'VCLinkerTool': { + 'IgnoreAllDefaultLibraries': "false", + }, + }, + }, + }, + }, + { + 'target_name': 'chrome_frame_strings', + 'type': 'none', + 'rules': [ + { + 'rule_name': 'grit', + 'extension': 'grd', + 'inputs': [ + '../tools/grit/grit.py', + ], + 'variables': { + 'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/chrome_frame', + }, + 'outputs': [ + '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/grit/<(RULE_INPUT_ROOT).h', + '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/<(RULE_INPUT_ROOT).pak', + ], + 'action': ['python', '<@(_inputs)', '-i', + '<(RULE_INPUT_PATH)', + 'build', '-o', '<(grit_out_dir)' + ], + 'message': 'Generating resources from <(RULE_INPUT_PATH)', + }, + ], + 'sources': [ + # Localizable resources. + 'resources/chrome_frame_strings.grd', + 'resources/chrome_frame_resources.grd', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '<(SHARED_INTERMEDIATE_DIR)/chrome_frame', + ], + }, + 'conditions': [ + ['OS=="win"', { + 'dependencies': ['../build/win/system.gyp:cygwin'], + }], + ], + }, + { + 'target_name': 'npchrome_tab', + 'type': 'shared_library', + 'msvs_guid': 'E3DE7E63-D3B6-4A9F-BCC4-5C8169E9C9F2', + 'dependencies': [ + 'base_noicu', + 'chrome_frame_npapi', + 'chrome_frame_strings', + 'chrome_launcher', + 'xulrunner_sdk', + '../chrome/chrome.gyp:common', + '../chrome/chrome.gyp:utility', + '../build/temp_gyp/googleurl.gyp:googleurl', + # FIXME(slightlyoff): + # gigantic hack to get these to build from main Chrome sln. + 'chrome_frame_perftests', + 'chrome_frame_tests', + 'chrome_frame_unittests', + 'chrome_frame_net_tests', + ], + 'sources': [ + 'bho.cc', + 'bho.h', + 'bho.rgs', + 'chrome_active_document.cc', + 'chrome_active_document.h', + 'chrome_active_document.rgs', + 'chrome_frame_activex.cc', + 'chrome_frame_activex.h', + 'chrome_frame_activex_base.h', + 'chrome_frame_activex.rgs', + 'chrome_frame_npapi.rgs', + 'chrome_frame_npapi_entrypoints.cc', + 'chrome_frame_reporting.cc', + 'chrome_frame_reporting.h', + 'chrome_protocol.cc', + 'chrome_protocol.h', + 'chrome_protocol.rgs', + 'chrome_tab.cc', + 'chrome_tab.def', + 'chrome_tab.h', + 'chrome_tab.idl', + # FIXME(slightlyoff): For chrome_tab.tlb. Giant hack until we can + # figure out something more gyp-ish. + 'resources/tlb_resource.rc', + 'chrome_tab.rgs', + 'chrome_tab_version.rc.version', + 'com_message_event.cc', + 'com_message_event.h', + 'com_type_info_holder.cc', + 'com_type_info_holder.h', + 'ff_30_privilege_check.cc', + 'ff_privilege_check.h', + 'find_dialog.cc', + 'find_dialog.h', + 'function_stub.h', + 'http_negotiate.h', + 'http_negotiate.cc', + 'icu_stubs.cc', + 'iids.cc', + 'in_place_menu.h', + 'ole_document_impl.h', + 'protocol_sink_wrap.cc', + 'protocol_sink_wrap.h', + 'resource.h', + 'script_security_manager.h', + 'sync_msg_reply_dispatcher.cc', + 'sync_msg_reply_dispatcher.h', + 'extra_system_apis.h', + 'urlmon_url_request.cc', + 'urlmon_url_request.h', + 'urlmon_upload_data_stream.cc', + 'urlmon_upload_data_stream.h', + 'vtable_patch_manager.cc', + 'vtable_patch_manager.h', + 'chrome_frame_histograms.h', + 'chrome_frame_histograms.cc', + ], + 'include_dirs': [ + # To allow including "chrome_tab.h" + '<(INTERMEDIATE_DIR)', + '<(INTERMEDIATE_DIR)/../npchrome_tab', + ], + 'conditions': [ + ['OS=="win"', { + # NOTE(slightlyoff): + # this is a fix for the include dirs length limit on the resource + # compiler, tickled by the xul_include_dirs variable + 'resource_include_dirs': [ + '<(INTERMEDIATE_DIR)' + ], + 'sources': [ + '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_resources.rc', + '<(SHARED_INTERMEDIATE_DIR)/chrome_frame/chrome_frame_strings.rc', + ], + 'dependencies': [ + '../breakpad/breakpad.gyp:breakpad_handler', + '../chrome/chrome.gyp:automation', + # Make the archive build happy. + '../chrome/chrome.gyp:syncapi', + # Installer + '../chrome/installer/installer.gyp:installer_util', + '../google_update/google_update.gyp:google_update', + # Crash Reporting + 'crash_reporting/crash_reporting.gyp:crash_report', + ], + 'msvs_settings': { + 'VCLinkerTool': { + 'OutputFile': + '..\\chrome\\$(ConfigurationName)\\servers\\$(ProjectName).dll', + 'DelayLoadDLLs': ['xpcom.dll', 'nspr4.dll'], + 'BaseAddress': '0x33000000', + # Set /SUBSYSTEM:WINDOWS (for consistency). + 'SubSystem': '2', + }, + }, + }], + ], + 'rules': [ + # Borrowed from chrome.gyp:chrome_dll_version, branding references + # removed + { + 'rule_name': 'version', + 'extension': 'version', + 'variables': { + 'version_py': '../chrome/tools/build/version.py', + 'version_path': '../chrome/VERSION', + 'template_input_path': 'chrome_tab_version.rc.version', + }, + 'inputs': [ + '<(template_input_path)', + '<(version_path)', + ], + 'outputs': [ + 'chrome_tab_version.rc', + ], + 'action': [ + 'python', + '<(version_py)', + '-f', '<(version_path)', + '<(template_input_path)', + '<@(_outputs)', + ], + 'process_outputs_as_sources': 1, + 'message': 'Generating version information in <(_outputs)' + }, + ], + }, + ], +} + +# vim: shiftwidth=2:et:ai:tabstop=2 + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/chrome_frame/chrome_tab.cc b/chrome_frame/chrome_tab.cc index dab6aac..a9423f3 100644 --- a/chrome_frame/chrome_tab.cc +++ b/chrome_frame/chrome_tab.cc @@ -3,6 +3,12 @@ // found in the LICENSE file. // chrome_tab.cc : Implementation of DLL Exports. + +// Include without path to make GYP build see it. +#include "chrome_tab.h" // NOLINT + +#include <atlsecurity.h> + #include "base/at_exit.h" #include "base/command_line.h" #include "base/file_util.h" @@ -23,10 +29,6 @@ #include "chrome_frame/resource.h" #include "chrome_frame/utils.h" -// Include without path to make GYP build see it. -#include "chrome_tab.h" // NOLINT -#include <atlsecurity.h> - static const wchar_t kBhoRegistryPath[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer" L"\\Browser Helper Objects"; @@ -148,6 +150,7 @@ const wchar_t kPostPlatformUAKey[] = const wchar_t kClockUserAgent[] = L"chromeframe"; // To delete the clock user agent, set value to NULL. +// TODO(tommi): Remove this method when it's no longer used. HRESULT SetClockUserAgent(const wchar_t* value) { HRESULT hr; RegKey ua_key; @@ -214,12 +217,14 @@ HRESULT RegisterChromeTabBHO() { ie_bho_key.WriteValue(kBhoNoLoadExplorerValue, 1); DLOG(INFO) << "Registered ChromeTab BHO"; - SetClockUserAgent(L"1"); + // We now add the chromeframe user agent at runtime. + // SetClockUserAgent(L"1"); RefreshElevationPolicy(); return S_OK; } HRESULT UnregisterChromeTabBHO() { + // TODO(tommi): remove this in future versions. SetClockUserAgent(NULL); RegKey ie_bho_key; diff --git a/chrome_frame/html_utils.cc b/chrome_frame/html_utils.cc index 944ea11..7ab1fd1 100644 --- a/chrome_frame/html_utils.cc +++ b/chrome_frame/html_utils.cc @@ -4,10 +4,14 @@ // #include "chrome_frame/html_utils.h" +#include <atlbase.h> +#include <urlmon.h> + #include "base/string_util.h" #include "base/string_tokenizer.h" +#include "chrome_frame/utils.h" -const wchar_t* kQuotes = L"\"'"; +const wchar_t kQuotes[] = L"\"'"; HTMLScanner::StringRange::StringRange() { } @@ -279,3 +283,73 @@ bool HTMLScanner::NextTag(StringRange* html_string, StringRange* tag) { return true; } +namespace http_utils { + +const char kChromeFrameUserAgent[] = "chromeframe"; + +const char* GetChromeFrameUserAgent() { + static char cf_user_agent[100] = {0}; + if (!cf_user_agent[0]) { + _pAtlModule->m_csStaticDataInitAndTypeInfo.Lock(); + if (!cf_user_agent[0]) { + uint32 version = 0; + GetModuleVersion(reinterpret_cast<HMODULE>(&__ImageBase), &version, NULL); + wsprintfA(cf_user_agent, "%s/%i.%i", kChromeFrameUserAgent, + HIWORD(version), LOWORD(version)); + } + _pAtlModule->m_csStaticDataInitAndTypeInfo.Unlock(); + } + return cf_user_agent; +} + +std::string AddChromeFrameToUserAgentValue(const std::string& value) { + if (value.empty()) { + DLOG(WARNING) << "empty user agent value"; + return ""; + } + + DCHECK_EQ(false, StartsWithASCII(value, "User-Agent:", true)); + + if (value.find(kChromeFrameUserAgent) != std::string::npos) { + // Our user agent has already been added. + return value; + } + + std::string ret(value); + ret += " "; + ret += GetChromeFrameUserAgent(); + + return ret; +} + +std::string GetDefaultUserAgentHeaderWithCFTag() { + std::string ua(GetDefaultUserAgent()); + return "User-Agent: " + AddChromeFrameToUserAgentValue(ua); +} + +std::string GetDefaultUserAgent() { + std::string ret; + DWORD size = MAX_PATH; // NOLINT + HRESULT hr = E_OUTOFMEMORY; + for (int retries = 1; hr == E_OUTOFMEMORY && retries <= 10; ++retries) { + hr = ::ObtainUserAgentString(0, WriteInto(&ret, size + 1), &size); + if (hr == E_OUTOFMEMORY) { + size = MAX_PATH * retries; + } else if (SUCCEEDED(hr)) { + // Truncate the extra allocation. + DCHECK(size > 0); // NOLINT + ret.resize(size - sizeof(char)); // NOLINT + } + } + + if (FAILED(hr)) { + NOTREACHED() << StringPrintf("ObtainUserAgentString==0x%08X", hr); + return ""; + } else { + DCHECK(ret.length() == lstrlenA(ret.c_str())); + } + + return ret; +} + +} // namespace http_utils diff --git a/chrome_frame/html_utils.h b/chrome_frame/html_utils.h index 4b89a2d..369950c 100644 --- a/chrome_frame/html_utils.h +++ b/chrome_frame/html_utils.h @@ -11,6 +11,7 @@ #include <vector> #include "base/basictypes.h" +#include "net/http/http_util.h" #include "testing/gtest/include/gtest/gtest_prod.h" // Forward declarations @@ -117,4 +118,27 @@ class HTMLScanner { DISALLOW_COPY_AND_ASSIGN(HTMLScanner); }; +namespace http_utils { + +// Adds "chromeframe/x.y" to the end of the User-Agent string (x.y is the +// version). If the cf tag has already been added to the string, +// the original string is returned. +std::string AddChromeFrameToUserAgentValue(const std::string& value); + +// Fetches the user agent from urlmon and adds chrome frame to the +// comment section. +// NOTE: The returned string includes the "User-Agent: " header name. +std::string GetDefaultUserAgentHeaderWithCFTag(); + +// Fetches the default user agent string from urlmon. +// This value does not include the "User-Agent:" header name. +std::string GetDefaultUserAgent(); + +// Returns the Chrome Frame user agent. E.g. "chromeframe/1.0". +// Note that in unit tests this will be "chromeframe/0.0" due to the version +// table not being present in the unit test executable. +const char* GetChromeFrameUserAgent(); + +} // namespace http_utils + #endif // CHROME_FRAME_HTML_UTILS_H_ diff --git a/chrome_frame/http_negotiate.cc b/chrome_frame/http_negotiate.cc new file mode 100644 index 0000000..efffeccc --- /dev/null +++ b/chrome_frame/http_negotiate.cc @@ -0,0 +1,164 @@ +// 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. + +#include "chrome_frame/http_negotiate.h" + +#include <atlbase.h> +#include <atlcom.h> + +#include "base/logging.h" +#include "base/scoped_ptr.h" +#include "base/string_util.h" + +#include "chrome_frame/html_utils.h" +#include "chrome_frame/urlmon_url_request.h" +#include "chrome_frame/utils.h" +#include "chrome_frame/vtable_patch_manager.h" + +static const int kHttpNegotiateBeginningTransactionIndex = 3; +static const int kHttpNegotiateOnResponseTransactionIndex = 4; + +BEGIN_VTABLE_PATCHES(IHttpNegotiate) + VTABLE_PATCH_ENTRY(kHttpNegotiateBeginningTransactionIndex, + HttpNegotiatePatch::BeginningTransaction) + VTABLE_PATCH_ENTRY(kHttpNegotiateOnResponseTransactionIndex, + HttpNegotiatePatch::OnResponse) +END_VTABLE_PATCHES() + +HttpNegotiatePatch::HttpNegotiatePatch() { +} + +HttpNegotiatePatch::~HttpNegotiatePatch() { +} + +// static +bool HttpNegotiatePatch::Initialize() { + if (IS_PATCHED(IHttpNegotiate)) { + DLOG(WARNING) << __FUNCTION__ << " called more than once."; + return true; + } + + // Use our UrlmonUrlRequest class as we need a temporary object that + // implements IBindStatusCallback. + CComObjectStackEx<UrlmonUrlRequest> request; + ScopedComPtr<IBindCtx> bind_ctx; + HRESULT hr = CreateAsyncBindCtx(0, &request, NULL, bind_ctx.Receive()); + DCHECK(SUCCEEDED(hr)) << "CreateAsyncBindCtx"; + if (bind_ctx) { + ScopedComPtr<IUnknown> bscb_holder; + bind_ctx->GetObjectParam(L"_BSCB_Holder_", bscb_holder.Receive()); + if (bscb_holder) { + hr = PatchHttpNegotiate(bscb_holder); + } else { + NOTREACHED() << "Failed to get _BSCB_Holder_"; + hr = E_UNEXPECTED; + } + bind_ctx.Release(); + } + + return SUCCEEDED(hr); +} + +// static +void HttpNegotiatePatch::Uninitialize() { + vtable_patch::UnpatchInterfaceMethods(IHttpNegotiate_PatchInfo); +} + +// static +HRESULT HttpNegotiatePatch::PatchHttpNegotiate(IUnknown* to_patch) { + DCHECK(to_patch); + DCHECK_IS_NOT_PATCHED(IHttpNegotiate); + + ScopedComPtr<IHttpNegotiate> http; + HRESULT hr = http.QueryFrom(to_patch); + if (FAILED(hr)) { + hr = DoQueryService(IID_IHttpNegotiate, to_patch, http.Receive()); + } + + if (http) { + hr = vtable_patch::PatchInterfaceMethods(http, IHttpNegotiate_PatchInfo); + DLOG_IF(ERROR, FAILED(hr)) + << StringPrintf("HttpNegotiate patch failed 0x%08X", hr); + } else { + DLOG(WARNING) + << StringPrintf("IHttpNegotiate not supported 0x%08X", hr); + } + + return hr; +} + +// static +HRESULT HttpNegotiatePatch::BeginningTransaction( + IHttpNegotiate_BeginningTransaction_Fn original, IHttpNegotiate* me, + LPCWSTR url, LPCWSTR headers, DWORD reserved, LPWSTR* additional_headers) { + DLOG(INFO) << __FUNCTION__ << " " << url; + + HRESULT hr = original(me, url, headers, reserved, additional_headers); + + if (FAILED(hr)) { + DLOG(WARNING) << __FUNCTION__ << " Delegate returned an error"; + return hr; + } + + static const char kLowerCaseUserAgent[] = "user-agent"; + + using net::HttpUtil; + + std::string ascii_headers; + if (*additional_headers) + ascii_headers = WideToASCII(*additional_headers); + + HttpUtil::HeadersIterator headers_iterator(ascii_headers.begin(), + ascii_headers.end(), "\r\n"); + std::string user_agent_value; + if (headers_iterator.AdvanceTo(kLowerCaseUserAgent)) { + user_agent_value = headers_iterator.values(); + } else if (headers != NULL) { + // See if there's a user-agent header specified in the original headers. + std::string original_headers(WideToASCII(headers)); + HttpUtil::HeadersIterator original_it(original_headers.begin(), + original_headers.end(), "\r\n"); + if (original_it.AdvanceTo(kLowerCaseUserAgent)) + user_agent_value = original_it.values(); + } + + // Use the default one if none was provided. + if (user_agent_value.empty()) + user_agent_value = http_utils::GetDefaultUserAgent(); + + // Now add chromeframe to it. + user_agent_value = http_utils::AddChromeFrameToUserAgentValue( + user_agent_value); + + // Build new headers, skip the existing user agent value from + // existing headers. + std::string new_headers; + headers_iterator.Reset(); + while (headers_iterator.GetNext()) { + std::string name(headers_iterator.name()); + if (!LowerCaseEqualsASCII(name, kLowerCaseUserAgent)) { + new_headers += name + ": " + headers_iterator.values() + "\r\n"; + } + } + + new_headers += "User-Agent: " + user_agent_value; + new_headers += "\r\n\r\n"; + + if (*additional_headers) + ::CoTaskMemFree(*additional_headers); + *additional_headers = reinterpret_cast<wchar_t*>(::CoTaskMemAlloc( + (new_headers.length() + 1) * sizeof(wchar_t))); + lstrcpyW(*additional_headers, ASCIIToWide(new_headers).c_str()); + + return hr; +} + +// static +HRESULT HttpNegotiatePatch::OnResponse(IHttpNegotiate_OnResponse_Fn original, + IHttpNegotiate* me, DWORD response_code, LPCWSTR response_header, + LPCWSTR request_header, LPWSTR* additional_request_headers) { + HRESULT hr = original(me, response_code, response_header, request_header, + additional_request_headers); + return hr; +} diff --git a/chrome_frame/http_negotiate.h b/chrome_frame/http_negotiate.h new file mode 100644 index 0000000..4a22d9c --- /dev/null +++ b/chrome_frame/http_negotiate.h @@ -0,0 +1,47 @@ +// 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. + +#ifndef CHROME_FRAME_HTTP_NEGOTIATE_H_ +#define CHROME_FRAME_HTTP_NEGOTIATE_H_ + +#include <urlmon.h> + +#include "base/basictypes.h" + +// Typedefs for IHttpNegotiate methods. +typedef HRESULT (STDMETHODCALLTYPE* IHttpNegotiate_BeginningTransaction_Fn)( + IHttpNegotiate* me, LPCWSTR url, LPCWSTR headers, DWORD reserved, + LPWSTR* additional_headers); +typedef HRESULT (STDMETHODCALLTYPE* IHttpNegotiate_OnResponse_Fn)( + IHttpNegotiate* me, DWORD response_code, LPCWSTR response_header, + LPCWSTR request_header, LPWSTR* additional_request_headers); + +// Patches methods of urlmon's IHttpNegotiate implementation for the purposes +// of adding to the http user agent header. +class HttpNegotiatePatch { + // class is not to be instantiated atm. + HttpNegotiatePatch(); + ~HttpNegotiatePatch(); + + public: + static bool Initialize(); + static void Uninitialize(); + + static STDMETHODIMP BeginningTransaction( + IHttpNegotiate_BeginningTransaction_Fn original, IHttpNegotiate* me, + LPCWSTR url, LPCWSTR headers, DWORD reserved, LPWSTR* additional_headers); + + static STDMETHODIMP OnResponse( + IHttpNegotiate_OnResponse_Fn original, IHttpNegotiate* me, + DWORD response_code, LPCWSTR response_header, LPCWSTR request_header, + LPWSTR* additional_request_headers); + + protected: + static HRESULT PatchHttpNegotiate(IUnknown* to_patch); + + private: + DISALLOW_COPY_AND_ASSIGN(HttpNegotiatePatch); +}; + +#endif // CHROME_FRAME_HTTP_NEGOTIATE_H_ diff --git a/chrome_frame/protocol_sink_wrap.cc b/chrome_frame/protocol_sink_wrap.cc index 5559e61..287cd36 100644 --- a/chrome_frame/protocol_sink_wrap.cc +++ b/chrome_frame/protocol_sink_wrap.cc @@ -6,7 +6,6 @@ #include "chrome_frame/protocol_sink_wrap.h" -#include "base/scoped_bstr_win.h" #include "base/logging.h" #include "base/registry.h" #include "base/scoped_bstr_win.h" @@ -233,44 +232,6 @@ bool ProtocolSinkWrap::Initialize(IInternetProtocol* protocol, return true; } -HRESULT WINAPI ProtocolSinkWrap::CheckOutgoingInterface(void* obj, - REFIID iid, LPVOID* ret, DWORD cookie) { - ProtocolSinkWrap* instance = reinterpret_cast<ProtocolSinkWrap*>(obj); - HRESULT hr = E_NOINTERFACE; - if (instance && instance->delegate_) - hr = instance->delegate_->QueryInterface(iid, ret); - -#ifndef NDEBUG - if (SUCCEEDED(hr)) { - wchar_t iid_string[64] = {0}; - StringFromGUID2(iid, iid_string, arraysize(iid_string)); - DLOG(INFO) << "Giving out wrapped interface: " << iid_string; - } -#endif - - return hr; -} - -HRESULT WINAPI ProtocolSinkWrap::IfDelegateSupports(void* obj, - REFIID iid, LPVOID* ret, DWORD cookie) { - HRESULT hr = E_NOINTERFACE; - ProtocolSinkWrap* instance = reinterpret_cast<ProtocolSinkWrap*>(obj); - if (instance && instance->delegate_) { - ScopedComPtr<IUnknown> original; - hr = instance->delegate_->QueryInterface(iid, - reinterpret_cast<void**>(original.Receive())); - if (original) { - IUnknown* supported_interface = reinterpret_cast<IUnknown*>( - reinterpret_cast<DWORD_PTR>(obj) + cookie); - supported_interface->AddRef(); - *ret = supported_interface; - hr = S_OK; - } - } - - return hr; -} - // IInternetProtocolSink methods STDMETHODIMP ProtocolSinkWrap::Switch(PROTOCOLDATA* protocol_data) { HRESULT hr = E_FAIL; @@ -282,7 +243,7 @@ STDMETHODIMP ProtocolSinkWrap::Switch(PROTOCOLDATA* protocol_data) { STDMETHODIMP ProtocolSinkWrap::ReportProgress(ULONG status_code, LPCWSTR status_text) { DLOG(INFO) << "ProtocolSinkWrap::ReportProgress: Code:" << status_code << - " Text: " << (status_text ? status_text : L""); + " Text: " << (status_text ? status_text : L""); if ((BINDSTATUS_MIMETYPEAVAILABLE == status_code) || (BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE == status_code)) { // If we have a MIMETYPE and that MIMETYPE is not "text/html". we don't @@ -412,8 +373,8 @@ STDMETHODIMP ProtocolSinkWrap::ReportResult(HRESULT result, DWORD error, } // IInternetBindInfoEx -STDMETHODIMP ProtocolSinkWrap::GetBindInfo( - DWORD* flags, BINDINFO* bind_info_ret) { +STDMETHODIMP ProtocolSinkWrap::GetBindInfo(DWORD* flags, + BINDINFO* bind_info_ret) { ScopedComPtr<IInternetBindInfo> bind_info; HRESULT hr = bind_info.QueryFrom(delegate_); if (bind_info) @@ -431,8 +392,8 @@ STDMETHODIMP ProtocolSinkWrap::GetBindString(ULONG string_type, return hr; } -STDMETHODIMP ProtocolSinkWrap::GetBindInfoEx(DWORD *flags, BINDINFO* bind_info, - DWORD* bindf2, DWORD *reserved) { +STDMETHODIMP ProtocolSinkWrap::GetBindInfoEx(DWORD* flags, BINDINFO* bind_info, + DWORD* bindf2, DWORD* reserved) { ScopedComPtr<IInternetBindInfoEx> bind_info_ex; HRESULT hr = bind_info_ex.QueryFrom(delegate_); if (bind_info_ex) @@ -664,8 +625,7 @@ HRESULT ProtocolSinkWrap::WebBrowserFromProtocolSink( ScopedComPtr<IInternetProtocolSink> ProtocolSinkWrap::MaybeWrapSink( IInternetProtocol* protocol, IInternetProtocolSink* prot_sink, const wchar_t* url) { - ScopedComPtr<IInternetProtocolSink> sink_to_use; - sink_to_use.QueryFrom(prot_sink); + ScopedComPtr<IInternetProtocolSink> sink_to_use(prot_sink); ScopedComPtr<IWebBrowser2> web_browser; WebBrowserFromProtocolSink(prot_sink, web_browser.Receive()); if (web_browser) { diff --git a/chrome_frame/protocol_sink_wrap.h b/chrome_frame/protocol_sink_wrap.h index bab018b..4152be0 100644 --- a/chrome_frame/protocol_sink_wrap.h +++ b/chrome_frame/protocol_sink_wrap.h @@ -9,6 +9,7 @@ #include <urlmon.h> #include <atlbase.h> #include <atlcom.h> + #include <map> #include <string> @@ -17,6 +18,7 @@ #include "base/scoped_comptr_win.h" #include "googleurl/src/gurl.h" #include "chrome_frame/ie8_types.h" +#include "chrome_frame/utils.h" #include "chrome_frame/vtable_patch_manager.h" // Typedefs for IInternetProtocol and related methods that we patch. @@ -60,11 +62,6 @@ class ProtocolSinkWrap public IUriContainer { public: -#define COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS(x) \ - COM_INTERFACE_ENTRY_FUNC(_ATL_IIDOF(x), \ - offsetofclass(x, _ComMapClass), \ - IfDelegateSupports) - BEGIN_COM_MAP(ProtocolSinkWrap) COM_INTERFACE_ENTRY(IInternetProtocolSink) COM_INTERFACE_ENTRY(IInternetBindInfo) @@ -77,7 +74,7 @@ BEGIN_COM_MAP(ProtocolSinkWrap) COM_INTERFACE_ENTRY(IInternetPriority) COM_INTERFACE_ENTRY(IWrappedProtocol) COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS(IUriContainer) - COM_INTERFACE_ENTRY_FUNC_BLIND(0, CheckOutgoingInterface) + COM_INTERFACE_BLIND_DELEGATE() END_COM_MAP() ProtocolSinkWrap(); @@ -94,17 +91,17 @@ END_COM_MAP() static void UnpatchProtocolHandlers(); // IInternetProtocol/Ex patches. - static HRESULT STDMETHODCALLTYPE OnStart(InternetProtocol_Start_Fn orig_start, + static STDMETHODIMP OnStart(InternetProtocol_Start_Fn orig_start, IInternetProtocol* protocol, LPCWSTR url, IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info, DWORD flags, HANDLE_PTR reserved); - static HRESULT STDMETHODCALLTYPE OnStartEx( + static STDMETHODIMP OnStartEx( InternetProtocol_StartEx_Fn orig_start_ex, IInternetProtocolEx* protocol, IUri* uri, IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info, DWORD flags, HANDLE_PTR reserved); - static HRESULT STDMETHODCALLTYPE OnRead(InternetProtocol_Read_Fn orig_read, + static STDMETHODIMP OnRead(InternetProtocol_Read_Fn orig_read, IInternetProtocol* protocol, void* buffer, ULONG size, ULONG* size_read); // IInternetProtocolSink methods @@ -155,6 +152,10 @@ END_COM_MAP() // ITransProtocolSink, // Undocumented // ITransactionInternal, // undocumented + IInternetProtocolSink* delegate() const { + return delegate_; + } + protected: enum RendererType { UNDETERMINED, @@ -172,10 +173,6 @@ END_COM_MAP() static ScopedComPtr<IInternetProtocolSink> MaybeWrapSink( IInternetProtocol* protocol, IInternetProtocolSink* prot_sink, const wchar_t* url); - static HRESULT WINAPI CheckOutgoingInterface(void* obj, REFIID iid, - LPVOID* ret, DWORD cookie); - static HRESULT WINAPI IfDelegateSupports(void* obj, REFIID iid, - LPVOID* ret, DWORD cookie); void DetermineRendererType(); HRESULT OnReadImpl(void* buffer, ULONG size, ULONG* size_read, @@ -207,15 +204,16 @@ END_COM_MAP() // http://b/issue?id=2102171 for details. // Remember original sink - CComPtr<IInternetProtocolSink> delegate_; + ScopedComPtr<IInternetProtocolSink> delegate_; + // Cannot take a reference on the protocol. IInternetProtocol* protocol_; RendererType renderer_type_; // Buffer for accumulated data including 1 extra for NULL-terminator char buffer_[kMaxContentSniffLength + 1]; - unsigned long buffer_size_; - unsigned long buffer_pos_; + unsigned long buffer_size_; // NOLINT + unsigned long buffer_pos_; // NOLINT // Accumulated result bool is_saved_result_; @@ -236,6 +234,4 @@ END_COM_MAP() DISALLOW_COPY_AND_ASSIGN(ProtocolSinkWrap); }; - #endif // CHROME_FRAME_PROTOCOL_SINK_WRAP_H_ - diff --git a/chrome_frame/test/html_util_unittests.cc b/chrome_frame/test/html_util_unittests.cc index 65e21c7..f654726 100644 --- a/chrome_frame/test/html_util_unittests.cc +++ b/chrome_frame/test/html_util_unittests.cc @@ -23,6 +23,8 @@ #include "chrome_frame/html_utils.h" #include "testing/gtest/include/gtest/gtest.h" +const char kChromeFrameUserAgent[] = "chromeframe"; + class HtmlUtilUnittest : public testing::Test { protected: // Constructor @@ -213,3 +215,97 @@ TEST_F(HtmlUtilUnittest, CloseTagInsideHTMLCommentTest) { scanner.GetTagsByName(L"meta", &tag_list, L"body"); ASSERT_TRUE(tag_list.empty()); } + +TEST_F(HtmlUtilUnittest, AddChromeFrameToUserAgentValue) { + struct TestCase { + std::string input_; + std::string expected_; + } test_cases[] = { + { + "", "" + }, { + "Mozilla/4.7 [en] (WinNT; U)", + "Mozilla/4.7 [en] (WinNT; U) chromeframe/0.0" + }, { + "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)", + "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT) chromeframe/0.0" + }, { + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; T312461; " + ".NET CLR 1.1.4322)", + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; T312461; " + ".NET CLR 1.1.4322) chromeframe/0.0" + }, { + "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 4.0) Opera 5.11 [en]", + "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 4.0) " + "Opera 5.11 [en] chromeframe/0.0" + }, { + "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) " + "Gecko/20030208 Netscape/7.02", + "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) " + "Gecko/20030208 Netscape/7.02 chromeframe/0.0" + }, { + "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040612 " + "Firefox/0.8", + "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040612 " + "Firefox/0.8 chromeframe/0.0" + }, { + "Mozilla/5.0 (compatible; Konqueror/3.2; Linux) (KHTML, like Gecko)", + "Mozilla/5.0 (compatible; Konqueror/3.2; Linux) " + "(KHTML, like Gecko) chromeframe/0.0" + }, { + "Lynx/2.8.4rel.1 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.6h", + "Lynx/2.8.4rel.1 libwww-FM/2.14 SSL-MM/1.4.1 " + "OpenSSL/0.9.6h chromeframe/0.0", + }, { + "Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.7.10) " + "Gecko/20050716 Firefox/1.0.6", + "Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.7.10) " + "Gecko/20050716 Firefox/1.0.6 chromeframe/0.0" + }, { + "Invalid/1.1 ((((((", + "Invalid/1.1 (((((( chromeframe/0.0", + }, { + "Invalid/1.1 ()))))", + "Invalid/1.1 ())))) chromeframe/0.0", + }, { + "Strange/1.1 ()", + "Strange/1.1 () chromeframe/0.0", + } + }; + + for (int i = 0; i < arraysize(test_cases); ++i) { + std::string new_ua( + http_utils::AddChromeFrameToUserAgentValue(test_cases[i].input_)); + EXPECT_EQ(test_cases[i].expected_, new_ua); + } + + // Now do the same test again, but test that we don't add the chromeframe + // tag if we've already added it. + for (int i = 0; i < arraysize(test_cases); ++i) { + std::string ua(test_cases[i].expected_); + std::string new_ua(http_utils::AddChromeFrameToUserAgentValue(ua)); + EXPECT_EQ(test_cases[i].expected_, new_ua); + } +} + +TEST_F(HtmlUtilUnittest, GetDefaultUserAgentHeaderWithCFTag) { + std::string ua(http_utils::GetDefaultUserAgentHeaderWithCFTag()); + EXPECT_NE(0, ua.length()); + EXPECT_NE(std::string::npos, ua.find("Mozilla")); + EXPECT_NE(std::string::npos, ua.find(kChromeFrameUserAgent)); +} + +TEST_F(HtmlUtilUnittest, GetDefaultUserAgent) { + std::string ua(http_utils::GetDefaultUserAgent()); + EXPECT_NE(0, ua.length()); + EXPECT_NE(std::string::npos, ua.find("Mozilla")); +} + +TEST_F(HtmlUtilUnittest, GetChromeFrameUserAgent) { + const char* call1 = http_utils::GetChromeFrameUserAgent(); + const char* call2 = http_utils::GetChromeFrameUserAgent(); + // Expect static buffer since caller does no cleanup. + EXPECT_EQ(call1, call2); + std::string ua(call1); + EXPECT_EQ("chromeframe/0.0", ua); +} diff --git a/chrome_frame/test/http_negotiate_unittest.cc b/chrome_frame/test/http_negotiate_unittest.cc new file mode 100644 index 0000000..a16a457 --- /dev/null +++ b/chrome_frame/test/http_negotiate_unittest.cc @@ -0,0 +1,118 @@ +// 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. + +#include <atlbase.h> +#include <atlcom.h> + +#include "base/string_util.h" +#include "chrome_frame/http_negotiate.h" +#include "chrome_frame/html_utils.h" +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +class HttpNegotiateTest : public testing::Test { + protected: + HttpNegotiateTest() { + } +}; + + +class TestHttpNegotiate + : public CComObjectRootEx<CComMultiThreadModel>, + public IHttpNegotiate { + public: + TestHttpNegotiate() + : beginning_transaction_ret_(S_OK), additional_headers_(NULL) { + } + +BEGIN_COM_MAP(TestHttpNegotiate) + COM_INTERFACE_ENTRY(IHttpNegotiate) +END_COM_MAP() + STDMETHOD(BeginningTransaction)(LPCWSTR url, LPCWSTR headers, // NOLINT + DWORD reserved, // NOLINT + LPWSTR* additional_headers) { // NOLINT + if (additional_headers_) { + int len = lstrlenW(additional_headers_); + len++; + *additional_headers = reinterpret_cast<wchar_t*>( + ::CoTaskMemAlloc(len * sizeof(wchar_t))); + lstrcpyW(*additional_headers, additional_headers_); + } + return beginning_transaction_ret_; + } + + STDMETHOD(OnResponse)(DWORD response_code, LPCWSTR response_header, + LPCWSTR request_header, + LPWSTR* additional_request_headers) { + return S_OK; + } + + HRESULT beginning_transaction_ret_; + const wchar_t* additional_headers_; +}; + +TEST_F(HttpNegotiateTest, BeginningTransaction) { + static const int kBeginningTransactionIndex = 3; + CComObjectStackEx<TestHttpNegotiate> test_http; + IHttpNegotiate_BeginningTransaction_Fn original = + reinterpret_cast<IHttpNegotiate_BeginningTransaction_Fn>( + (*reinterpret_cast<void***>( + static_cast<IHttpNegotiate*>(&test_http)))[kBeginningTransactionIndex]); + + std::wstring cf_ua( + ASCIIToWide(http_utils::GetDefaultUserAgentHeaderWithCFTag())); + std::wstring cf_tag( + ASCIIToWide(http_utils::GetChromeFrameUserAgent())); + + EXPECT_NE(std::wstring::npos, cf_ua.find(cf_tag)); + + struct TestCase { + const std::wstring original_headers_; + const std::wstring delegate_additional_; + const std::wstring expected_additional_; + HRESULT delegate_return_value_; + } test_cases[] = { + { L"Accept: */*\r\n\r\n", + L"", + cf_ua + L"\r\n\r\n", + S_OK }, + { L"Accept: */*\r\n\r\n", + L"", + L"", + E_OUTOFMEMORY }, + { L"", + L"Accept: */*\r\n\r\n", + L"Accept: */*\r\n" + cf_ua + L"\r\n\r\n", + S_OK }, + { L"User-Agent: Bingo/1.0\r\n\r\n", + L"", + L"User-Agent: Bingo/1.0 " + cf_tag + L"\r\n\r\n", + S_OK }, + { L"User-Agent: NotMe/1.0\r\n\r\n", + L"User-Agent: MeMeMe/1.0\r\n\r\n", + L"User-Agent: MeMeMe/1.0 " + cf_tag + L"\r\n\r\n", + S_OK }, + { L"", + L"User-Agent: MeMeMe/1.0\r\n\r\n", + L"User-Agent: MeMeMe/1.0 " + cf_tag + L"\r\n\r\n", + S_OK }, + }; + + for (int i = 0; i < arraysize(test_cases); ++i) { + TestCase& test = test_cases[i]; + wchar_t* additional = NULL; + test_http.beginning_transaction_ret_ = test.delegate_return_value_; + test_http.additional_headers_ = test.delegate_additional_.c_str(); + HttpNegotiatePatch::BeginningTransaction(original, &test_http, + L"http://www.google.com", test.original_headers_.c_str(), 0, + &additional); + EXPECT_TRUE(additional != NULL); + + if (additional) { + // Check against the expected additional headers. + EXPECT_EQ(test.expected_additional_, std::wstring(additional)); + ::CoTaskMemFree(additional); + } + } +} diff --git a/chrome_frame/utils.h b/chrome_frame/utils.h index baece31..7b56621 100644 --- a/chrome_frame/utils.h +++ b/chrome_frame/utils.h @@ -9,6 +9,7 @@ #include <string> #include "base/basictypes.h" +#include "base/logging.h" // utils.h : Various utility functions and classes @@ -202,7 +203,8 @@ bool IsOptInUrl(const wchar_t* url); // A shortcut for QueryService template <typename T> -HRESULT DoQueryService(const CLSID& class_id, IUnknown* unk, T** service) { +HRESULT DoQueryService(const IID& service_id, IUnknown* unk, T** service) { + DCHECK(service); if (!unk) return E_INVALIDARG; ScopedComPtr<IServiceProvider> service_provider; @@ -210,7 +212,7 @@ HRESULT DoQueryService(const CLSID& class_id, IUnknown* unk, T** service) { if (!service_provider) return hr; - return service_provider->QueryService(class_id, service); + return service_provider->QueryService(service_id, service); } // Get url (display name) from a moniker, |bind_context| is optional @@ -225,4 +227,60 @@ bool IsValidUrlScheme(const std::wstring& url, bool is_privileged); // This returns the base directory in which to store user profiles. bool GetUserProfileBaseDirectory(std::wstring* path); +// See COM_INTERFACE_BLIND_DELEGATE below for details. +template <class T> +STDMETHODIMP CheckOutgoingInterface(void* obj, REFIID iid, void** ret, + DWORD cookie) { + T* instance = reinterpret_cast<T*>(obj); + HRESULT hr = E_NOINTERFACE; + IUnknown* delegate = instance ? instance->delegate() : NULL; + if (delegate) { + hr = delegate->QueryInterface(iid, ret); +#if !defined(NDEBUG) + if (SUCCEEDED(hr)) { + wchar_t iid_string[64] = {0}; + StringFromGUID2(iid, iid_string, arraysize(iid_string)); + DLOG(INFO) << __FUNCTION__ << " Giving out wrapped interface: " + << iid_string; + } +#endif + } + + return hr; +} + +// See COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS below for details. +template <class T> +STDMETHODIMP QueryInterfaceIfDelegateSupports(void* obj, REFIID iid, + void** ret, DWORD cookie) { + HRESULT hr = E_NOINTERFACE; + T* instance = reinterpret_cast<T*>(obj); + IUnknown* delegate = instance ? instance->delegate() : NULL; + if (delegate) { + ScopedComPtr<IUnknown> original; + hr = delegate->QueryInterface(iid, + reinterpret_cast<void**>(original.Receive())); + if (original) { + IUnknown* supported_interface = reinterpret_cast<IUnknown*>( + reinterpret_cast<DWORD_PTR>(obj) + cookie); + supported_interface->AddRef(); + *ret = supported_interface; + hr = S_OK; + } + } + + return hr; +} + +// Same as COM_INTERFACE_ENTRY but relies on the class to implement a +// delegate() method that returns a pointer to the delegated COM object. +#define COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS(x) \ + COM_INTERFACE_ENTRY_FUNC(_ATL_IIDOF(x), \ + offsetofclass(x, _ComMapClass), \ + QueryInterfaceIfDelegateSupports<_ComMapClass>) + +// Queries the delegated COM object for an interface, bypassing the wrapper. +#define COM_INTERFACE_BLIND_DELEGATE() \ + COM_INTERFACE_ENTRY_FUNC_BLIND(0, CheckOutgoingInterface<_ComMapClass>) + #endif // CHROME_FRAME_UTILS_H_ diff --git a/chrome_frame/vtable_patch_manager.cc b/chrome_frame/vtable_patch_manager.cc index 0b9f79aa..c070211 100644 --- a/chrome_frame/vtable_patch_manager.cc +++ b/chrome_frame/vtable_patch_manager.cc @@ -4,7 +4,10 @@ #include "chrome_frame/vtable_patch_manager.h" +#include <algorithm> + #include "base/logging.h" +#include "base/scoped_ptr.h" #include "chrome_frame/function_stub.h" @@ -88,4 +91,72 @@ HRESULT UnpatchInterfaceMethods(MethodPatchInfo* patches) { return S_OK; } +// Disabled for now as we're not using it atm. +#if 0 + +DynamicPatchManager::DynamicPatchManager(const MethodPatchInfo* patch_prototype) + : patch_prototype_(patch_prototype) { + DCHECK(patch_prototype_); + DCHECK(patch_prototype_->stub_ == NULL); +} + +DynamicPatchManager::~DynamicPatchManager() { + UnpatchAll(); +} + +HRESULT DynamicPatchManager::PatchObject(void* unknown) { + int patched_methods = 0; + for (; patch_prototype_[patched_methods].index_ != -1; patched_methods++) { + // If you hit this, then you are likely using the prototype instance for + // patching in _addition_ to this class. This is not a good idea :) + DCHECK(patch_prototype_[patched_methods].stub_ == NULL); + } + + // Prepare a new patch object using the patch info from the prototype. + int mem_size = sizeof(PatchedObject) + + sizeof(MethodPatchInfo) * patched_methods; + PatchedObject* entry = reinterpret_cast<PatchedObject*>(new char[mem_size]); + entry->vtable_ = GetIFVTable(unknown); + memcpy(entry->patch_info_, patch_prototype_, + sizeof(MethodPatchInfo) * (patched_methods + 1)); + + patch_list_lock_.Acquire(); + + // See if we've already patched this vtable before. + // The search is done via the == operator of the PatchedObject class. + PatchList::const_iterator it = std::find(patch_list_.begin(), + patch_list_.end(), entry); + HRESULT hr; + if (it == patch_list_.end()) { + hr = PatchInterfaceMethods(unknown, entry->patch_info_); + if (SUCCEEDED(hr)) { + patch_list_.push_back(entry); + entry = NULL; // Ownership transferred to the array. + } + } else { + hr = S_FALSE; + } + + patch_list_lock_.Release(); + + delete entry; + + return hr; +} + +bool DynamicPatchManager::UnpatchAll() { + patch_list_lock_.Acquire(); + PatchList::iterator it; + for (it = patch_list_.begin(); it != patch_list_.end(); it++) { + UnpatchInterfaceMethods((*it)->patch_info_); + delete (*it); + } + patch_list_.clear(); + patch_list_lock_.Release(); + + return true; +} + +#endif // disabled DynamicPatchManager + } // namespace vtable_patch diff --git a/chrome_frame/vtable_patch_manager.h b/chrome_frame/vtable_patch_manager.h index 944b9ef..f326def 100644 --- a/chrome_frame/vtable_patch_manager.h +++ b/chrome_frame/vtable_patch_manager.h @@ -2,11 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_FRAME_COMMON_VTABLE_PATCH_MANAGER_H_ -#define CHROME_FRAME_COMMON_VTABLE_PATCH_MANAGER_H_ +#ifndef CHROME_FRAME_VTABLE_PATCH_MANAGER_H_ +#define CHROME_FRAME_VTABLE_PATCH_MANAGER_H_ #include <windows.h> +#include <list> + +#include "base/lock.h" + struct FunctionStub; // This namespace provides methods to patch VTable methods of COM interfaces. namespace vtable_patch { @@ -39,13 +43,46 @@ HRESULT PatchInterfaceMethods(void* unknown, MethodPatchInfo* patches); // The last entry of patches must have index_ set to -1. HRESULT UnpatchInterfaceMethods(MethodPatchInfo* patches); +// Disabled as we're not using it atm. +#if 0 +// Used when dynamically patching zero or more (usually more than 1) +// implementations of a particular interface. +class DynamicPatchManager { + public: + explicit DynamicPatchManager(const MethodPatchInfo* patch_prototype); + ~DynamicPatchManager(); + + // Returns S_OK if the object was successfully patched, S_FALSE if it was + // already patched or an error value if something bad happened. + HRESULT PatchObject(void* unknown); + + bool UnpatchAll(); + + protected: + struct PatchedObject { + void* vtable_; + MethodPatchInfo patch_info_[1]; + + // Used to match PatchedObject instances based on the vtable when + // searching through the patch list. + bool operator==(const PatchedObject& that) const { + return vtable_ == that.vtable_; + } + }; + + typedef std::list<PatchedObject*> PatchList; + const MethodPatchInfo* patch_prototype_; + mutable Lock patch_list_lock_; + PatchList patch_list_; +}; +#endif // disable DynamicPatchManager + } // namespace vtable_patch // Begins the declaration of a VTable patch // @param IFName The name of the interface to patch #define BEGIN_VTABLE_PATCHES(IFName) \ vtable_patch::MethodPatchInfo IFName##_PatchInfo[] = { - // Defines a single method patch in a VTable // @param index The index of the method to patch // @param PatchFunction The patch function @@ -55,10 +92,27 @@ HRESULT UnpatchInterfaceMethods(MethodPatchInfo* patches); NULL, \ }, +#define DCHECK_IS_NOT_PATCHED(IFName) \ + for (vtable_patch::MethodPatchInfo* it = IFName##_PatchInfo; \ + it->index_ != -1; ++it) { \ + DCHECK(it->stub_ == NULL); \ + } + +#define DCHECK_IS_PATCHED(IFName) \ + for (vtable_patch::MethodPatchInfo* it = IFName##_PatchInfo; \ + it->index_ != -1; ++it) { \ + DCHECK(it->stub_ != NULL); \ + } + +// Checks if the interface is patched. Note that only the first method +// is checked and subsequent methods are assumed to have the same state. +#define IS_PATCHED(IFName) \ + (IFName##_PatchInfo[0].stub_ != NULL) + // Ends the declaration of a VTable patch by adding an entry with // index set to -1. #define END_VTABLE_PATCHES() \ -1, NULL, NULL \ }; -#endif // CHROME_FRAME_COMMON_VTABLE_PATCH_MANAGER_H_ +#endif // CHROME_FRAME_VTABLE_PATCH_MANAGER_H_ |