diff options
author | siggi@chromium.org <siggi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-23 16:48:19 +0000 |
---|---|---|
committer | siggi@chromium.org <siggi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-23 16:48:19 +0000 |
commit | 054f941471fb9a62e585f91d04bcba73c8d03b9f (patch) | |
tree | abc12b2695a1b2e83291b23159df451acc0e34f6 /ceee | |
parent | db300df5f6b747e9575e3740083f2ec328b09a2e (diff) | |
download | chromium_src-054f941471fb9a62e585f91d04bcba73c8d03b9f.zip chromium_src-054f941471fb9a62e585f91d04bcba73c8d03b9f.tar.gz chromium_src-054f941471fb9a62e585f91d04bcba73c8d03b9f.tar.bz2 |
Revert 67102 - Use async COM to service tab executor requests.
Change to proxy/stub marshaling from typelib marshaling,
with manual registration of proxy/stubs. Moving away from
registered proxy/stubs is desireable in the context of
upcoming GCF autoupdate changes, and this is an opportune
moment.
Implement an async ICeeeTabExecutor that defers execution
until a posted message is processed. This avoids (I hope)
processing reentrantly on out-of-apartment invocations in IE,
which has a tendency to lead to deadlocks and general
nastyness.
BUG=none
TEST=unittests in change
Review URL: http://codereview.chromium.org/4845001
TBR=siggi@chromium.org
Review URL: http://codereview.chromium.org/5343001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67103 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ceee')
-rw-r--r-- | ceee/ie/broker/broker.gyp | 1 | ||||
-rw-r--r-- | ceee/ie/broker/broker_module.cc | 9 | ||||
-rw-r--r-- | ceee/ie/ie.gyp | 21 | ||||
-rw-r--r-- | ceee/ie/plugin/bho/browser_helper_object.cc | 29 | ||||
-rw-r--r-- | ceee/ie/plugin/bho/browser_helper_object.h | 11 | ||||
-rw-r--r-- | ceee/ie/plugin/bho/browser_helper_object.rgs | 1 | ||||
-rw-r--r-- | ceee/ie/plugin/bho/browser_helper_object_unittest.cc | 7 | ||||
-rw-r--r-- | ceee/ie/plugin/bho/executor.cc | 233 | ||||
-rw-r--r-- | ceee/ie/plugin/bho/executor.h | 107 | ||||
-rw-r--r-- | ceee/ie/plugin/bho/executor_com_unittest.cc | 762 | ||||
-rw-r--r-- | ceee/ie/plugin/bho/testing_invoke_executor.cc | 96 | ||||
-rw-r--r-- | ceee/ie/plugin/toolband/resource.h | 2 | ||||
-rw-r--r-- | ceee/ie/plugin/toolband/toolband.gyp | 30 | ||||
-rw-r--r-- | ceee/ie/plugin/toolband/toolband.idl | 19 | ||||
-rw-r--r-- | ceee/ie/plugin/toolband/toolband.rc | 1 | ||||
-rw-r--r-- | ceee/ie/plugin/toolband/toolband_module.cc | 36 | ||||
-rw-r--r-- | ceee/ie/plugin/toolband/toolband_proxy.cc | 150 | ||||
-rw-r--r-- | ceee/ie/plugin/toolband/toolband_proxy.h | 29 | ||||
-rw-r--r-- | ceee/ie/plugin/toolband/toolband_proxy.rgs | 11 |
19 files changed, 26 insertions, 1529 deletions
diff --git a/ceee/ie/broker/broker.gyp b/ceee/ie/broker/broker.gyp index f1f3220..e669013 100644 --- a/ceee/ie/broker/broker.gyp +++ b/ceee/ie/broker/broker.gyp @@ -133,7 +133,6 @@ '../common/common.gyp:ie_common_settings', '../common/common.gyp:ie_guids', '../plugin/toolband/toolband.gyp:toolband_idl', - '../plugin/toolband/toolband.gyp:toolband_proxy_lib', '../../../base/base.gyp:base', '../../../breakpad/breakpad.gyp:breakpad_handler', '../../../ceee/common/common.gyp:ceee_common', diff --git a/ceee/ie/broker/broker_module.cc b/ceee/ie/broker/broker_module.cc index 252e6a4..0d7a0eb 100644 --- a/ceee/ie/broker/broker_module.cc +++ b/ceee/ie/broker/broker_module.cc @@ -18,7 +18,6 @@ #include "ceee/ie/broker/executors_manager.h" #include "ceee/ie/broker/resource.h" #include "ceee/ie/broker/window_events_funnel.h" -#include "ceee/ie/plugin/toolband/toolband_proxy.h" #include "ceee/ie/common/crash_reporter.h" #include "ceee/common/com_utils.h" #include "chrome/common/url_constants.h" @@ -154,14 +153,6 @@ HRESULT CeeeBrokerModule::InitializeCom() { DLOG_IF(WARNING, FAILED(hr)) << "IGlobalOptions::Set failed " << com::LogHr(hr); - // Register the executor proxy/stubs. - // Note that this registers the proxy/stub class objects for all threads - // in the multithreaded apartment. - if (!RegisterProxyStubs(NULL)) { - LOG(ERROR) << "Failed to register executor proxy/stubs"; - return E_UNEXPECTED; - } - // The above is best-effort, don't bail on error. return S_OK; } diff --git a/ceee/ie/ie.gyp b/ceee/ie/ie.gyp index 3a04651..91e7ebf 100644 --- a/ceee/ie/ie.gyp +++ b/ceee/ie/ie.gyp @@ -18,23 +18,6 @@ ] }, { - 'target_name': 'testing_invoke_executor', - 'type': 'executable', - 'sources': [ - 'plugin/bho/testing_invoke_executor.cc', - ], - 'dependencies': [ - '../../base/base.gyp:base', - '../common/common.gyp:ceee_common', - 'common/common.gyp:ie_guids', - 'plugin/toolband/toolband.gyp:toolband_idl', - 'plugin/toolband/toolband.gyp:toolband_proxy_lib', - ], - 'libraries': [ - 'rpcrt4.lib', - ], - }, - { 'target_name': 'ie_unittests', 'type': 'executable', 'sources': [ @@ -58,7 +41,6 @@ 'plugin/bho/dom_utils_unittest.cc', 'plugin/bho/events_funnel_unittest.cc', 'plugin/bho/executor_unittest.cc', - 'plugin/bho/executor_com_unittest.cc', 'plugin/bho/extension_port_manager.cc', 'plugin/bho/frame_event_handler_unittest.cc', 'plugin/bho/infobar_events_funnel_unittest.cc', @@ -96,7 +78,6 @@ }, }, 'dependencies': [ - 'testing_invoke_executor', 'common/common.gyp:ie_common', 'common/common.gyp:ie_common_settings', 'common/common.gyp:ie_guids', @@ -108,7 +89,6 @@ 'plugin/toolband/toolband.gyp:ceee_ie_lib', 'plugin/toolband/toolband.gyp:ie_toolband_common', 'plugin/toolband/toolband.gyp:toolband_idl', - 'plugin/toolband/toolband.gyp:toolband_proxy_lib', '../../base/base.gyp:base', '../../breakpad/breakpad.gyp:breakpad_handler', '../testing/sidestep/sidestep.gyp:sidestep', @@ -151,7 +131,6 @@ 'plugin/bho/bho.gyp:bho', 'plugin/scripting/scripting.gyp:scripting', 'plugin/toolband/toolband.gyp:toolband_idl', - 'plugin/toolband/toolband.gyp:toolband_proxy_lib', '../../base/base.gyp:base', '../../testing/gmock.gyp:gmock', '../../testing/gtest.gyp:gtest', diff --git a/ceee/ie/plugin/bho/browser_helper_object.cc b/ceee/ie/plugin/bho/browser_helper_object.cc index d0f5cdc..e237442 100644 --- a/ceee/ie/plugin/bho/browser_helper_object.cc +++ b/ceee/ie/plugin/bho/browser_helper_object.cc @@ -27,7 +27,6 @@ #include "ceee/ie/plugin/bho/cookie_accountant.h" #include "ceee/ie/plugin/bho/http_negotiate.h" #include "ceee/ie/plugin/scripting/script_host.h" -#include "ceee/ie/plugin/toolband/toolband_proxy.h" #include "chrome/browser/automation/extension_automation_constants.h" #include "chrome/browser/extensions/extension_tabs_module_constants.h" #include "chrome/common/automation_constants.h" @@ -152,25 +151,14 @@ STDMETHODIMP BrowserHelperObject::SetSite(IUnknown* site) { // We're being initialized. hr = Initialize(site); - // Release the site, and tear down our own state in case of failure. - if (FAILED(hr)) { - TearDown(); + // Release the site in case of failure. + if (FAILED(hr)) SuperSite::SetSite(NULL); - } } return hr; } -HRESULT BrowserHelperObject::RegisterProxies() { - return RegisterProxyStubs(&proxy_stub_cookies_) ? S_OK : E_UNEXPECTED; -} - -void BrowserHelperObject::UnregisterProxies() { - UnregisterProxyStubs(proxy_stub_cookies_); - proxy_stub_cookies_.clear(); -} - HRESULT BrowserHelperObject::GetParentBrowser(IWebBrowser2* browser, IWebBrowser2** parent_browser) { DCHECK(browser != NULL); @@ -257,18 +245,13 @@ HRESULT BrowserHelperObject::Initialize(IUnknown* site) { DCHECK(SUCCEEDED(hr)) << "InitializeChromeFrameHost failed " << com::LogHr(hr); if (FAILED(hr)) { + TearDown(); return hr; } // Initialize the extension port manager. extension_port_manager_.Initialize(chrome_frame_host_); - // Register the proxy/stubs for the executor. - // Note the proxy registration function will have logged what occurred. - hr = RegisterProxies(); - if (FAILED(hr)) - return hr; - // Preemptively feed the broker with an executor in our thread. hr = GetBrokerRegistrar(&broker_registrar_); LOG_IF(ERROR, FAILED(hr)) << "Failed to create broker, hr=" << @@ -297,18 +280,21 @@ HRESULT BrowserHelperObject::Initialize(IUnknown* site) { CComQIPtr<IServiceProvider> service_provider(site); DCHECK(service_provider); if (service_provider == NULL) { + TearDown(); return E_FAIL; } hr = ConnectSinks(service_provider); DCHECK(SUCCEEDED(hr)) << "ConnectSinks failed " << com::LogHr(hr); if (FAILED(hr)) { + TearDown(); return hr; } hr = GetTabWindow(service_provider); DCHECK(SUCCEEDED(hr)) << "GetTabWindow failed " << com::LogHr(hr); if (FAILED(hr)) { + TearDown(); return hr; } @@ -377,9 +363,6 @@ HRESULT BrowserHelperObject::TearDown() { } chrome_frame_host_.Release(); - // Unregister the proxy/stubs for the executor. - UnregisterProxies(); - return S_OK; } diff --git a/ceee/ie/plugin/bho/browser_helper_object.h b/ceee/ie/plugin/bho/browser_helper_object.h index 8f79453..039b305 100644 --- a/ceee/ie/plugin/bho/browser_helper_object.h +++ b/ceee/ie/plugin/bho/browser_helper_object.h @@ -163,11 +163,6 @@ class ATL_NO_VTABLE BrowserHelperObject // @} protected: - // Register proxy/stubs for executor interfaces. - virtual HRESULT RegisterProxies(); - // Unregister proxy/stubs for executor interfaces. - virtual void UnregisterProxies(); - typedef base::win::ScopedComPtr<IContentScriptNativeApi, &GUID_NULL> ScopedContentScriptNativeApiPtr; typedef base::win::ScopedComPtr<IDispatch> ScopedDispatchPtr; @@ -225,8 +220,6 @@ class ATL_NO_VTABLE BrowserHelperObject // Initializes the BHO to the given site. // Called from SetSite. - // @note On failure the state of the BHO may be inconsistent, - // so a TearDown may be needed. HRESULT Initialize(IUnknown* site); // Tears down an initialized bho. @@ -378,10 +371,6 @@ class ATL_NO_VTABLE BrowserHelperObject BrokerRpcClient broker_rpc_; private: - // The BHO registers proxy/stubs for the CEEE executor on initialization. - // These are the cookies to allow us to unregister then on teardown. - std::vector<DWORD> proxy_stub_cookies_; - // Used during initialization to get the tab information from Chrome and // register ourselves with the broker. HRESULT RegisterTabInfo(); diff --git a/ceee/ie/plugin/bho/browser_helper_object.rgs b/ceee/ie/plugin/bho/browser_helper_object.rgs index fd794ab..f7331a6 100644 --- a/ceee/ie/plugin/bho/browser_helper_object.rgs +++ b/ceee/ie/plugin/bho/browser_helper_object.rgs @@ -4,6 +4,7 @@ NoRemove CLSID { InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } + 'TypeLib' = s '{7C09079D-F9CB-4E9E-9293-D224B071D8BA}' } } } diff --git a/ceee/ie/plugin/bho/browser_helper_object_unittest.cc b/ceee/ie/plugin/bho/browser_helper_object_unittest.cc index be970e8..8bbac5c 100644 --- a/ceee/ie/plugin/bho/browser_helper_object_unittest.cc +++ b/ceee/ie/plugin/bho/browser_helper_object_unittest.cc @@ -133,13 +133,6 @@ class TestingBrowserHelperObject MOCK_METHOD2(GetParentBrowser, HRESULT(IWebBrowser2*, IWebBrowser2**)); - // Neuter the proxy registration/unregistration. - HRESULT RegisterProxies() { - return S_OK; - } - void UnregisterProxies() { - } - // Pulicize using BrowserHelperObject::HandleNavigateComplete; diff --git a/ceee/ie/plugin/bho/executor.cc b/ceee/ie/plugin/bho/executor.cc index a6e6f7b..d32410f 100644 --- a/ceee/ie/plugin/bho/executor.cc +++ b/ceee/ie/plugin/bho/executor.cc @@ -36,6 +36,7 @@ #include "base/json/json_writer.h" #include "base/logging.h" #include "base/values.h" +#include "base/scoped_ptr.h" #include "base/stringprintf.h" #include "base/utf_string_conversions.h" #include "ceee/common/com_utils.h" @@ -45,7 +46,6 @@ #include "ceee/ie/plugin/bho/frame_event_handler.h" #include "ceee/ie/plugin/bho/infobar_manager.h" #include "ceee/ie/plugin/bho/tab_window_manager.h" -#include "ceee/ie/plugin/toolband/toolband_proxy.h" #include "chrome_frame/utils.h" #include "broker_lib.h" // NOLINT @@ -146,14 +146,6 @@ LRESULT CeeeExecutorCreator::GetMsgProc(int code, WPARAM wparam, return 0; } - // Register the proxy/stubs for the executor. - // We don't make arrangements to unregister them here as we don't - // expect we'll ever unload from the process. - // TODO(siggi@chromium.org): Is it worth arranging for unregistration - // in this case? - if (!RegisterProxyStubs(NULL)) - LOG(ERROR) << "Executor Creator failed to register proxy/stubs"; - CComPtr<ICeeeWindowExecutor> executor; HRESULT hr = executor.CoCreateInstance(CLSID_CeeeExecutor); LOG_IF(ERROR, FAILED(hr)) << "Failed to create Executor, hr=" << @@ -187,229 +179,6 @@ LRESULT CeeeExecutorCreator::GetMsgProc(int code, WPARAM wparam, return ::CallNextHookEx(NULL, code, wparam, lparam); } -AsyncTabCall::AsyncTabCall() : task_hr_(E_PENDING), task_(NULL) { - VLOG(1) << "AsyncTabCall " << this << " created"; -} - -AsyncTabCall::~AsyncTabCall() { - VLOG(1) << "AsyncTabCall " << this << " deleted"; -} - -HRESULT AsyncTabCall::CreateInitialized(ICeeeTabExecutor* executor, - IUnknown* outer, - IUnknown** async_call) { - CComPolyObject<AsyncTabCall>* async_tab_call = NULL; - HRESULT hr = CComPolyObject<AsyncTabCall>::CreateInstance( - outer, &async_tab_call); - - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create async tab call " << com::LogHr(hr); - return hr; - } - DCHECK(async_tab_call != NULL); - - hr = async_tab_call->m_contained.Initialize(executor); - if (FAILED(hr)) { - delete async_tab_call; - LOG(ERROR) << "Async tab call initialization failed " << com::LogHr(hr); - } - - return async_tab_call->QueryInterface(async_call); -} - -HRESULT AsyncTabCall::Initialize(ICeeeTabExecutor* executor) { - DCHECK(executor != NULL); - executor_ = executor; - return S_OK; -} - -STDMETHODIMP AsyncTabCall::Begin_Initialize(CeeeWindowHandle hwnd) { - DCHECK(task_hr_ == E_PENDING && task_ == NULL); - task_hr_ = executor_->Initialize(hwnd); - return Signal(); -} - -STDMETHODIMP AsyncTabCall::Finish_Initialize() { - return task_hr_; -} - -// A noop function. -static void Noop() { -} - -STDMETHODIMP AsyncTabCall::Begin_GetTabInfo() { - DCHECK(task_hr_ == E_PENDING && task_ == NULL); - - // We do all the work on Finish_GetTabInfo, so schedule only a noop - // invocation. Alternatively we could schedule NULL here, though that - // would make it more difficult to distinguish error cases. - return ScheduleTask(NewRunnableFunction(Noop)); -} - -STDMETHODIMP AsyncTabCall::Finish_GetTabInfo(CeeeTabInfo *tab_info) { - return executor_->GetTabInfo(tab_info); -} - -STDMETHODIMP AsyncTabCall::Begin_Navigate(BSTR url, long flags, BSTR target) { - DCHECK(task_hr_ == E_PENDING && task_ == NULL); - - if (!ScheduleTask(NewRunnableMethod(this, - &AsyncTabCall::NavigateImpl, - CComBSTR(url), - flags, - CComBSTR(target)))) { - LOG(ERROR) << "Failed to schedule navigation task"; - return E_OUTOFMEMORY; - } - - return S_OK; -} - -STDMETHODIMP AsyncTabCall::Finish_Navigate() { - return task_hr_; -} - -STDMETHODIMP AsyncTabCall::Begin_InsertCode(BSTR code, - BSTR file, - BOOL all_frames, - CeeeTabCodeType type) { - DCHECK(task_hr_ == E_PENDING && task_ == NULL); - - if (!ScheduleTask(NewRunnableMethod(this, - &AsyncTabCall::InsertCodeImpl, - CComBSTR(code), - CComBSTR(file), - all_frames, - type))) { - LOG(ERROR) << "Failed to schedule insert code task"; - return E_OUTOFMEMORY; - } - - return S_OK; -} - -STDMETHODIMP AsyncTabCall::Finish_InsertCode() { - return task_hr_; -} - -void AsyncTabCall::NavigateImpl(const CComBSTR& url, - long flags, - const CComBSTR& target) { - task_hr_ = executor_->Navigate(url, flags, target); -} - -void AsyncTabCall::InsertCodeImpl(const CComBSTR& code, - const CComBSTR& file, - BOOL all_frames, - CeeeTabCodeType type) { - task_hr_ = executor_->InsertCode(code, file, all_frames, type); -} - -int AsyncTabCall::OnCreate(LPCREATESTRUCT lpCreateStruct) { - // Our window maintains a self-reference to our object. - GetUnknown()->AddRef(); - return 1; -} - -LRESULT AsyncTabCall::OnExecuteTask( - UINT msg, WPARAM wparam, LPARAM lparam, BOOL& handled) { - VLOG(1) << "OnExecuteTask for " << this; - - if (task_.get() != NULL) { - task_->Run(); - task_.reset(); - } - - // Signal the call done, this'll cause the Finish_ call to execute. - Signal(); - - DestroyWindow(); - return 1; -} - -void AsyncTabCall::OnFinalMessage(HWND window) { - // Release our window's self-reference. - GetUnknown()->Release(); -} - -bool AsyncTabCall::ScheduleTask(Task* task) { - DCHECK(task != NULL); - DCHECK(m_hWnd == NULL); - - if (Create(HWND_MESSAGE) == NULL) { - LOG(ERROR) << "Failed to create window"; - - delete task; - return false; - } - DCHECK(m_hWnd != NULL); - - // Schedule the task for later by posting a message. - task_.reset(task); - PostMessage(kExecuteTaskMessage); - - return true; -} - -HRESULT AsyncTabCall::Signal() { - // We need to explicitly query for ISynchronize, because we're - // most likely aggregated, and the implementation is on our - // controlling outer. - CComPtr<ISynchronize> sync; - HRESULT hr = GetUnknown()->QueryInterface(&sync); - if (sync == NULL) { - LOG(ERROR) << "Failed to retrieve ISynchronize " << com::LogHr(hr); - return hr; - } - DCHECK(sync != NULL); - - hr = sync->Signal(); - if (FAILED(hr)) - LOG(ERROR) << "Failed to signal " << com::LogHr(hr); - - return hr; -} - -CeeeExecutor::CeeeExecutor() : hwnd_(NULL) { -} - -CeeeExecutor::~CeeeExecutor() { -} - -HRESULT CeeeExecutor::CreateTabCall(ICeeeTabExecutor* executor, - IUnknown *outer, - REFIID riid2, - IUnknown **out) { - CComPtr<IUnknown> tab_call; - HRESULT hr = AsyncTabCall::CreateInitialized(executor, outer, &tab_call); - if (SUCCEEDED(hr)) - hr = tab_call->QueryInterface(riid2, reinterpret_cast<void**>(out)); - - if (FAILED(hr)) { - delete tab_call; - LOG(ERROR) << "Async executor initialization failed " << com::LogHr(hr); - } - - return hr; -} - -STDMETHODIMP CeeeExecutor::CreateCall(REFIID async_iid, - IUnknown *outer, - REFIID requested_iid, - IUnknown **out) { - DCHECK(outer != NULL); - DCHECK(out != NULL); - // Null for safety. - *out = NULL; - - if (async_iid == IID_AsyncICeeeTabExecutor) { - return CreateTabCall(this, outer, requested_iid, out); - } else { - LOG(ERROR) << "Unexpected IID to CreateCall"; - return E_NOINTERFACE; - } -} - HRESULT CeeeExecutor::Initialize(CeeeWindowHandle hwnd) { DCHECK(hwnd); hwnd_ = reinterpret_cast<HWND>(hwnd); diff --git a/ceee/ie/plugin/bho/executor.h b/ceee/ie/plugin/bho/executor.h index eeea590..379ba32 100644 --- a/ceee/ie/plugin/bho/executor.h +++ b/ceee/ie/plugin/bho/executor.h @@ -14,7 +14,6 @@ #include <string.h> #include "base/scoped_ptr.h" -#include "base/task.h" #include "ceee/ie/plugin/bho/infobar_manager.h" #include "ceee/ie/plugin/toolband/resource.h" @@ -70,98 +69,12 @@ class ATL_NO_VTABLE CeeeExecutorCreator long current_thread_id_; }; -// Implements an asynchronous call object for ICeeeTabExecutor. -// This is instantiated through the executor's ICallFactory::CreateCall method. -// For asynchronous methods, it posts a window message and processes the -// method completion when the message is dispatched. This is done to avoid -// performing significant operations inside IE, reentrantly during an -// outgoing out-of-apartment call. During those times, IE and the various -// third-party addons performing such outcalls tend to be in a fragile state. -// @note the COM marshaling machinery will instantiate a new one of these for -// each call it handles, so these are not implemented to cope with reuse. -class AsyncTabCall - : public CComObjectRootEx<CComSingleThreadModel>, - public CComCoClass<AsyncTabCall>, - public CWindowImpl<AsyncTabCall>, - public AsyncICeeeTabExecutor { - public: - DECLARE_GET_CONTROLLING_UNKNOWN() - - BEGIN_COM_MAP(AsyncTabCall) - COM_INTERFACE_ENTRY(AsyncICeeeTabExecutor) - COM_INTERFACE_ENTRY_AUTOAGGREGATE(IID_ISynchronize, - synchronize_.p, - CLSID_ManualResetEvent) - END_COM_MAP() - - // The window message we post to ourselves. - static const uint32 kExecuteTaskMessage = WM_USER; - - BEGIN_MSG_MAP(AsyncTabCall) - MSG_WM_CREATE(OnCreate) - MESSAGE_HANDLER(kExecuteTaskMessage, OnExecuteTask) - END_MSG_MAP() - - AsyncTabCall(); - ~AsyncTabCall(); - - // Creates an initialized instance. Aggregated if outer is non-NULL. - // @param executor the executor instance we invoke on. - // @param outer the controlling outer or NULL. - // @param async_call on success, returns the new AsyncTabCall. - static HRESULT CreateInitialized(ICeeeTabExecutor* executor, - IUnknown* outer, - IUnknown** async_call); - - static bool ImplementsThreadSafeReferenceCounting() { - return false; - } - - // @name AsyncICeeeTabExecutor implementation. - // @{ - STDMETHOD(Begin_Initialize)(CeeeWindowHandle hwnd); - STDMETHOD(Finish_Initialize)(); - STDMETHOD(Begin_GetTabInfo)(); - STDMETHOD(Finish_GetTabInfo)(CeeeTabInfo *tab_info); - STDMETHOD(Begin_Navigate)(BSTR url, long flags, BSTR target); - STDMETHOD(Finish_Navigate)(); - STDMETHOD(Begin_InsertCode)(BSTR code, BSTR file, BOOL all_frames, - CeeeTabCodeType type); - STDMETHOD(Finish_InsertCode)(); - // @} - - // Initialize a newly constructed async tab call. - // This is public only for unittesting. - HRESULT Initialize(ICeeeTabExecutor* executor); - - private: - void NavigateImpl(const CComBSTR& url, long flags, const CComBSTR& target); - void InsertCodeImpl(const CComBSTR& code, - const CComBSTR& file, - BOOL all_frames, - CeeeTabCodeType type); - - int OnCreate(LPCREATESTRUCT lpCreateStruct); - LRESULT OnExecuteTask(UINT msg, WPARAM wparam, LPARAM lparam, BOOL& handled); - virtual void OnFinalMessage(HWND window); - bool ScheduleTask(Task* task); - HRESULT Signal(); - - CComPtr<IUnknown> synchronize_; - CComPtr<ICeeeTabExecutor> executor_; - - // The task we've scheduled for execution. - scoped_ptr<Task> task_; - HRESULT task_hr_; -}; - // The executor object that is instantiated in the destination thread and // then called to... execute stuff... class ATL_NO_VTABLE CeeeExecutor : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CeeeExecutor, &CLSID_CeeeExecutor>, public IObjectWithSiteImpl<CeeeExecutor>, - public ICallFactory, public ICeeeWindowExecutor, public ICeeeTabExecutor, public ICeeeCookieExecutor, @@ -172,7 +85,6 @@ class ATL_NO_VTABLE CeeeExecutor DECLARE_NOT_AGGREGATABLE(CeeeExecutor) BEGIN_COM_MAP(CeeeExecutor) COM_INTERFACE_ENTRY(IObjectWithSite) - COM_INTERFACE_ENTRY(ICallFactory) COM_INTERFACE_ENTRY(ICeeeWindowExecutor) COM_INTERFACE_ENTRY(ICeeeTabExecutor) COM_INTERFACE_ENTRY(ICeeeCookieExecutor) @@ -181,17 +93,6 @@ class ATL_NO_VTABLE CeeeExecutor DECLARE_PROTECT_FINAL_CONSTRUCT() DECLARE_CLASSFACTORY() - CeeeExecutor(); - ~CeeeExecutor(); - - // @name ICallFactory implementation. - // @{ - STDMETHOD(CreateCall)(REFIID async_iid, - IUnknown *outer, - REFIID requested_iid, - IUnknown **out); - // @} - // @name ICeeeWindowExecutor implementation. // @{ STDMETHOD(Initialize)(CeeeWindowHandle hwnd); @@ -230,13 +131,9 @@ class ATL_NO_VTABLE CeeeExecutor STDMETHOD(OnTopFrameBeforeNavigate)(BSTR url); // @} - protected: - // Unittest seam. - virtual HRESULT CreateTabCall(ICeeeTabExecutor* executor, - IUnknown *outer, - REFIID riid2, - IUnknown **out); + CeeeExecutor() : hwnd_(NULL) {} + protected: // Get the IWebBrowser2 interface of the // frame event host that was set as our site. virtual HRESULT GetWebBrowser(IWebBrowser2** browser); diff --git a/ceee/ie/plugin/bho/executor_com_unittest.cc b/ceee/ie/plugin/bho/executor_com_unittest.cc deleted file mode 100644 index c1379a8..0000000 --- a/ceee/ie/plugin/bho/executor_com_unittest.cc +++ /dev/null @@ -1,762 +0,0 @@ -// Copyright (c) 2010 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. -// -// Executor COM implementation unit tests. - -#include "ceee/ie/plugin/bho/executor.h" - -#include <shlobj.h> -#include <atlbase.h> -#include "base/command_line.h" -#include "base/file_path.h" -#include "base/message_loop.h" -#include "base/path_service.h" -#include "base/process_util.h" -#include "base/thread.h" -#include "base/win/registry.h" -#include "base/win/windows_version.h" -#include "ceee/common/initializing_coclass.h" -#include "ceee/ie/plugin/toolband/toolband_proxy.h" -#include "ceee/ie/testing/mock_broker_and_friends.h" -#include "ceee/testing/utils/instance_count_mixin.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -namespace { - -using testing::_; -using testing::DoAll; -using testing::Invoke; -using testing::InSequence; -using testing::IsNull; -using testing::NotNull; -using testing::Return; -using testing::StrEq; -using testing::StrictMock; -using testing::InstanceCountMixin; -using testing::InstanceCountMixinBase; - -class ISynchronizeMock: public ISynchronize { - public: - MOCK_METHOD2_WITH_CALLTYPE(__stdcall, Wait, - HRESULT(DWORD flags, DWORD milliseconds)); - MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Signal, HRESULT()); - MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Reset, HRESULT()); -}; - -class TestISynchronize - : public CComObjectRootEx<CComMultiThreadModel>, - public InitializingCoClass<TestISynchronize>, - public InstanceCountMixin<TestISynchronize>, - public StrictMock<ISynchronizeMock> { - public: - DECLARE_GET_CONTROLLING_UNKNOWN() - BEGIN_COM_MAP(TestISynchronize) - COM_INTERFACE_ENTRY(ISynchronize) - COM_INTERFACE_ENTRY_AGGREGATE_BLIND(async_call_.p) - END_COM_MAP() - - TestISynchronize() { - } - - ~TestISynchronize() { - } - - HRESULT Initialize(TestISynchronize** self) { - *self = this; - return S_OK; - } - - void set_async_call(IUnknown* async_call) { async_call_ = async_call; } - - private: - // This is the async call instance we aggregate. - CComPtr<IUnknown> async_call_; -}; - -class MockCeeeExecutor - : public CComObjectRootEx<CComSingleThreadModel>, - public InitializingCoClass<MockCeeeExecutor>, - public InstanceCountMixin<MockCeeeExecutor>, - public StrictMock<testing::MockCeeeWindowExecutorImpl>, - public StrictMock<testing::MockCeeeTabExecutorImpl>, - public StrictMock<testing::MockCeeeCookieExecutorImpl>, - public StrictMock<testing::MockCeeeInfobarExecutorImpl> { - public: - BEGIN_COM_MAP(MockCeeeExecutor) - COM_INTERFACE_ENTRY(ICeeeWindowExecutor) - COM_INTERFACE_ENTRY(ICeeeTabExecutor) - COM_INTERFACE_ENTRY(ICeeeCookieExecutor) - COM_INTERFACE_ENTRY(ICeeeInfobarExecutor) - END_COM_MAP() - - HRESULT Initialize(MockCeeeExecutor** self) { - *self = this; - return S_OK; - } -}; - -class TestAsyncTabCall - : public AsyncTabCall, - public InitializingCoClass<TestAsyncTabCall>, - public InstanceCountMixin<TestAsyncTabCall> { - public: -}; - -// A test subclass of CeeeExecutor to allow testing -// the async behavior of ICeeeTabExecutor. -class TestCeeeExecutor - : public CeeeExecutor, - public InitializingCoClass<TestCeeeExecutor>, - public InstanceCountMixin<TestCeeeExecutor> { - public: - HRESULT Initialize(TestCeeeExecutor** self) { - *self = this; - return S_OK; - } - - // Mock out the ICeeeTabExecutor interface implementation. - MOCK_METHOD1_WITH_CALLTYPE(__stdcall, Initialize, - HRESULT(CeeeWindowHandle hwnd)); - MOCK_METHOD1_WITH_CALLTYPE(__stdcall, GetTabInfo, - HRESULT(CeeeTabInfo* tab_info)); - MOCK_METHOD3_WITH_CALLTYPE(__stdcall, Navigate, - HRESULT(BSTR url, long flags, BSTR target)); - MOCK_METHOD4_WITH_CALLTYPE(__stdcall, InsertCode, - HRESULT(BSTR code, BSTR file, BOOL all_frames, CeeeTabCodeType type)); - - MOCK_METHOD4(CreateTabCall, HRESULT(ICeeeTabExecutor* executor, - IUnknown *outer, - REFIID riid2, - IUnknown **out)); -}; - -class RemoteObjectHost; -DISABLE_RUNNABLE_METHOD_REFCOUNT(RemoteObjectHost); - -class RemoteObjectHost { - public: - RemoteObjectHost() : remote_thread_("RemoteObjectHost") { - } - - ~RemoteObjectHost() { - remote_git_ptr_.Revoke(); - remote_object_.Release(); - } - - void HostObject(IUnknown* object) { - // Spin up our thread and initialize it. - ASSERT_TRUE(remote_thread_.StartWithOptions( - base::Thread::Options(MessageLoop::TYPE_UI, 0))); - - // Marshal the object in the thread. - RunSync( - NewRunnableMethod(this, &RemoteObjectHost::InitRemoteThread, object)); - - // Marshal the contained object back as an IUnknown. - ASSERT_HRESULT_SUCCEEDED(remote_git_ptr_.CopyTo(&remote_object_)); - } - - void RunSync(Task* task) { - ScopedHandle event(::CreateEvent(NULL, TRUE, FALSE, NULL)); - - remote_thread_.message_loop()->PostTask(FROM_HERE, task); - remote_thread_.message_loop()->PostTask(FROM_HERE, - NewRunnableFunction(::SetEvent, event.Get())); - - ASSERT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(event.Get(), INFINITE)); - } - - void InitRemoteThread(IUnknown* object) { - EXPECT_HRESULT_SUCCEEDED(::CoInitialize(NULL)); - EXPECT_HRESULT_SUCCEEDED(remote_git_ptr_.Attach(object)); - } - - public: - // The git pointer is created in the remote_thread_. - CComGITPtr<IUnknown> remote_git_ptr_; - // And this is a local proxy to the remote object. - CComPtr<IUnknown> remote_object_; - base::Thread remote_thread_; -}; - -ACTION_P(QuitMessageLoop, message_loop) { - message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); -} - -static const HRESULT E_CAFEBABE = 0xCAFEBABE; - -class ExecutorComTest: public testing::Test { - public: - ExecutorComTest() - : executor_(NULL), - synchronize_(NULL), - loop_(MessageLoop::TYPE_UI) { - } - - static bool ImplementsThreadSafeReferenceCounting() { - return true; - } - - virtual void SetUp() { - ASSERT_HRESULT_SUCCEEDED(::CoInitialize(NULL)); - - ASSERT_HRESULT_SUCCEEDED(TestCeeeExecutor::CreateInitialized( - &executor_, &executor_keeper_)); - ASSERT_HRESULT_SUCCEEDED(TestISynchronize::CreateInitialized( - &synchronize_, &synchronize_keeper_)); - } - - virtual void TearDown() { - executor_ = NULL; - executor_keeper_.Release(); - - synchronize_->set_async_call(NULL); - synchronize_ = NULL; - synchronize_keeper_.Release(); - - UnregisterProxies(); - - // We want everything unregistered before we CoUninitialize. - ::CoUninitialize(); - - EXPECT_EQ(0, InstanceCountMixinBase::all_instance_count()); - } - - void RegisterProxies() { - ASSERT_TRUE(RegisterProxyStubs(&proxy_cookies_)); - } - - void UnregisterProxies() { - if (!proxy_cookies_.empty()) { - UnregisterProxyStubs(proxy_cookies_); - proxy_cookies_.clear(); - } - } - - static void CreateTestTabCallImpl(ICeeeTabExecutor* executor, - IUnknown *outer, - REFIID riid2, - IUnknown **out) { - CComPolyObject<TestAsyncTabCall>* async_tab_call = NULL; - ASSERT_HRESULT_SUCCEEDED( - CComPolyObject<TestAsyncTabCall>::CreateInstance( - outer, &async_tab_call)); - ASSERT_TRUE(async_tab_call != NULL); - ASSERT_HRESULT_SUCCEEDED(async_tab_call->m_contained.Initialize(executor)); - ASSERT_HRESULT_SUCCEEDED( - async_tab_call->QueryInterface(riid2, reinterpret_cast<void**>(out))); - } - - void ExpectCreateTabCall(TestCeeeExecutor* executor) { - EXPECT_CALL(*executor, CreateTabCall(executor, _, _, _)) - .WillOnce( - DoAll( - Invoke(&ExecutorComTest::CreateTestTabCallImpl), - Return(S_OK))); - } - - void CreateTabExecutor(AsyncICeeeTabExecutor** executor_call) { - // Retrieve the call factory. - CComPtr<ICallFactory> call_factory; - ASSERT_HRESULT_SUCCEEDED(executor_keeper_->QueryInterface(&call_factory)); - ASSERT_TRUE(call_factory != NULL); - - // Create the call object. - ASSERT_NO_FATAL_FAILURE(ExpectCreateTabCall(executor_)); - CComPtr<IUnknown> async_unknown; - ASSERT_HRESULT_SUCCEEDED( - call_factory->CreateCall(IID_AsyncICeeeTabExecutor, - synchronize_->GetControllingUnknown(), - IID_IUnknown, - &async_unknown)); - synchronize_->set_async_call(async_unknown); - async_unknown.Release(); - - ASSERT_HRESULT_SUCCEEDED( - synchronize_keeper_->QueryInterface(executor_call)); - } - - void RunShortMessageLoop() { - // Set up the expectations we have for invocations - // during the brief message loop. - EXPECT_CALL(*synchronize_, Signal()) - .WillOnce( - DoAll( - QuitMessageLoop(&loop_), - Return(S_OK))); - - // And run the loop. - loop_.Run(); - } - - protected: - // This test executor is created on setup. - TestCeeeExecutor* executor_; - CComPtr<ICeeeTabExecutor> executor_keeper_; - - TestISynchronize* synchronize_; - CComPtr<ISynchronize> synchronize_keeper_; - - MessageLoop loop_; - - std::vector<DWORD> proxy_cookies_; -}; - -DISABLE_RUNNABLE_METHOD_REFCOUNT(ExecutorComTest); - -static const wchar_t* kUrl = L"http://www.google.com/"; -static long kFlags = 74565; -static const wchar_t* kTarget = L"_blank"; - -TEST_F(ExecutorComTest, MarshalingFailsWithNoProxy) { - RemoteObjectHost host; - ASSERT_NO_FATAL_FAILURE(host.HostObject(executor_keeper_)); - - // We expect failure, unmarshaling shouldn't be possible - // without the proxies registered in our (source) thread. - CComPtr<ICeeeTabExecutor> executor; - ASSERT_HRESULT_FAILED(host.remote_object_.QueryInterface(&executor)); -} - -TEST_F(ExecutorComTest, MarshalingFailsWithNoLocalProxy) { - RemoteObjectHost host; - ASSERT_NO_FATAL_FAILURE(host.HostObject(executor_keeper_)); - - std::vector<DWORD> invoker_cookies; - host.RunSync(NewRunnableFunction(RegisterProxyStubs, &invoker_cookies)); - - // We expect failure, unmarshaling shouldn't be possible - // without the proxies registered in our (source) thread. - CComPtr<ICeeeTabExecutor> executor; - ASSERT_HRESULT_FAILED(host.remote_object_.QueryInterface(&executor)); -} - -TEST_F(ExecutorComTest, MarshalingSucceedsWithProxiesRegistered) { - RemoteObjectHost host; - ASSERT_NO_FATAL_FAILURE(host.HostObject(executor_keeper_)); - - std::vector<DWORD> invoker_cookies; - host.RunSync(NewRunnableFunction(RegisterProxyStubs, &invoker_cookies)); - - // Register proxies in our thread. - RegisterProxies(); - - // We expect success as both home and away proxies - // are now registered. - CComPtr<ICeeeTabExecutor> executor; - ASSERT_HRESULT_SUCCEEDED(host.remote_object_.QueryInterface(&executor)); -} - -TEST_F(ExecutorComTest, AllProxiesAreRegistered) { - // Create the mock executor. - CComPtr<IUnknown> mock_keeper; - MockCeeeExecutor* mock_executor = NULL; - ASSERT_HRESULT_SUCCEEDED( - MockCeeeExecutor::CreateInitialized(&mock_executor, &mock_keeper)); - - RemoteObjectHost host; - ASSERT_NO_FATAL_FAILURE(host.HostObject(mock_keeper)); - - // Register proxies on both sides. - std::vector<DWORD> invoker_cookies; - host.RunSync(NewRunnableFunction(RegisterProxyStubs, &invoker_cookies)); - RegisterProxies(); - - CComPtr<ICeeeWindowExecutor> window_executor; - EXPECT_HRESULT_SUCCEEDED( - host.remote_object_.QueryInterface(&window_executor)); - - CComPtr<ICeeeTabExecutor> tab_executor; - EXPECT_HRESULT_SUCCEEDED( - host.remote_object_.QueryInterface(&tab_executor)); - - CComPtr<ICeeeCookieExecutor> cookie_executor; - EXPECT_HRESULT_SUCCEEDED( - host.remote_object_.QueryInterface(&cookie_executor)); - - CComPtr<ICeeeInfobarExecutor> infobar_executor; - EXPECT_HRESULT_SUCCEEDED( - host.remote_object_.QueryInterface(&infobar_executor)); -} - -TEST_F(ExecutorComTest, UnregisterProxiesWorks) { - RemoteObjectHost host; - ASSERT_NO_FATAL_FAILURE(host.HostObject(executor_keeper_)); - - std::vector<DWORD> invoker_cookies; - host.RunSync(NewRunnableFunction(RegisterProxyStubs, &invoker_cookies)); - - // Register proxies in our thread. - RegisterProxies(); - - // We expect success as both home and away proxies - // are now registered. - CComPtr<ICeeeTabExecutor> executor; - ASSERT_HRESULT_SUCCEEDED(host.remote_object_.QueryInterface(&executor)); - executor.Release(); - - // Now unregister the proxies on our side and try again. - // We need to release the local proxy, as it'll cache any interfaces - // we've already queried. - UnregisterProxies(); - host.remote_object_.Release(); - ASSERT_HRESULT_SUCCEEDED(host.remote_git_ptr_.CopyTo(&host.remote_object_)); - ASSERT_HRESULT_FAILED(host.remote_object_.QueryInterface(&executor)); -} - -TEST_F(ExecutorComTest, ImplementsCallFactory) { - CComPtr<ICallFactory> call_factory; - ASSERT_HRESULT_SUCCEEDED(executor_keeper_->QueryInterface(&call_factory)); - ASSERT_TRUE(call_factory != NULL); -} - -TEST_F(ExecutorComTest, SyncInitialize) { - CComPtr<AsyncICeeeTabExecutor> executor_call; - ASSERT_NO_FATAL_FAILURE(CreateTabExecutor(&executor_call)); - - static const CeeeWindowHandle kWindow = 0xF1F2F3F4; - // We expect this to run synchronously at begin time. - EXPECT_CALL(*synchronize_, Signal()); - EXPECT_CALL(*executor_, Initialize(kWindow)) - .WillOnce(Return(E_CAFEBABE)); - - ASSERT_HRESULT_SUCCEEDED(executor_call->Begin_Initialize(kWindow)); - - // Verify that we return the exepected HRESULT. - ASSERT_EQ(E_CAFEBABE, executor_call->Finish_Initialize()); -} - -TEST_F(ExecutorComTest, AsyncGetTabInfo) { - CComPtr<AsyncICeeeTabExecutor> executor_call; - ASSERT_NO_FATAL_FAILURE(CreateTabExecutor(&executor_call)); - ASSERT_HRESULT_SUCCEEDED(executor_call->Begin_GetTabInfo()); - - ASSERT_NO_FATAL_FAILURE(RunShortMessageLoop()); - - // We expect the call after the message loop, as there's an out - // param we have to cater to. - CeeeTabInfo tab_info = {}; - EXPECT_CALL(*executor_, GetTabInfo(&tab_info)) - .WillOnce(Return(E_CAFEBABE)); - - // Verify that we return the expected HRESULT. - ASSERT_EQ(E_CAFEBABE, executor_call->Finish_GetTabInfo(&tab_info)); -} - -TEST_F(ExecutorComTest, AsyncNavigate) { - CComPtr<AsyncICeeeTabExecutor> executor_call; - ASSERT_NO_FATAL_FAILURE(CreateTabExecutor(&executor_call)); - - ASSERT_HRESULT_SUCCEEDED(executor_call->Begin_Navigate( - CComBSTR(kUrl), kFlags, CComBSTR(kTarget))); - - // We expect the call to from within the message loop. - EXPECT_CALL(*executor_, Navigate(StrEq(kUrl), kFlags, StrEq(kTarget))) - .WillOnce(Return(E_CAFEBABE)); - - ASSERT_NO_FATAL_FAILURE(RunShortMessageLoop()); - - // Verify that we return the exepected HRESULT. - ASSERT_EQ(E_CAFEBABE, executor_call->Finish_Navigate()); -} - -TEST_F(ExecutorComTest, AsyncInsertCode) { - CComPtr<AsyncICeeeTabExecutor> executor_call; - ASSERT_NO_FATAL_FAILURE(CreateTabExecutor(&executor_call)); - const wchar_t* kCode = L"window.alert(\"You've been had.\")"; - const wchar_t* kFile = L"CONSOLE"; - ASSERT_HRESULT_SUCCEEDED(executor_call->Begin_InsertCode( - CComBSTR(kCode), CComBSTR(kFile), TRUE, kCeeeTabCodeTypeJs)); - - // Now set up the expectations we have for invocations - // during the brief message loop. - EXPECT_CALL(*executor_, - InsertCode(StrEq(kCode), StrEq(kFile), TRUE, kCeeeTabCodeTypeJs)) - .WillOnce(Return(E_CAFEBABE)); - - ASSERT_NO_FATAL_FAILURE(RunShortMessageLoop()); - - // Verify that we return the expected HRESULT. - ASSERT_EQ(E_CAFEBABE, executor_call->Finish_InsertCode()); -} - -// This unittest fails due to a bug in COM, whereby asynchronous calls across -// apartments in the same process cause an access violation on freeing an -// invalid pointer. -// This is true as of 15 Nov 2010, leaving this around in hopes Microsoft -// comes through with a fix. -TEST_F(ExecutorComTest, DISABLED_CrossApartmentCall) { - RemoteObjectHost host; - ASSERT_NO_FATAL_FAILURE(host.HostObject(executor_keeper_)); - - // Register home and away proxies. - std::vector<DWORD> invoker_cookies; - host.RunSync(NewRunnableFunction(RegisterProxyStubs, &invoker_cookies)); - RegisterProxies(); - - CComPtr<ICeeeTabExecutor> executor; - ASSERT_HRESULT_SUCCEEDED(host.remote_object_.QueryInterface(&executor)); - - // A navigation call should go through with no trouble. - EXPECT_CALL(*executor_, Navigate(StrEq(kUrl), 0, StrEq(kTarget))) - .WillOnce(Return(S_OK)); - - EXPECT_HRESULT_SUCCEEDED( - executor->Navigate(CComBSTR(kUrl), 0, CComBSTR(kTarget))); -} - -class TestClassFactory - : public CComObjectRootEx<CComSingleThreadModel>, - public InitializingCoClass<TestClassFactory>, - public IClassFactory { - public: - BEGIN_COM_MAP(TestClassFactory) - COM_INTERFACE_ENTRY(IClassFactory) - END_COM_MAP() - - TestClassFactory() : executor_(NULL) { - } - - HRESULT Initialize(TestCeeeExecutor* executor) { - executor_ = executor; - return S_OK; - } - - STDMETHOD(CreateInstance)(IUnknown *outer, REFIID riid, void **out) { - if (outer != NULL) { - ADD_FAILURE() << "Attempted aggregation in CreateInstance"; - return CLASS_E_NOAGGREGATION; - } - - return executor_->QueryInterface(riid, out); - } - - STDMETHOD(LockServer)(BOOL lock) { - ADD_FAILURE() << "Unexpected call to LockServer"; - return E_NOTIMPL; - } - - TestCeeeExecutor* executor_; -}; - -const wchar_t* kHKCUReplacement = - L"Software\\Google\\ExecutorComInvocationTest\\HKCU"; - -// Registry script to register iid->async iid mapping. -const wchar_t* kRegScript = - L"%ROOT% {\n" - L" Software {\n" - L" Classes {\n" - L" NoRemove 'Interface' {\n" - L" '%IID%' = s '%NAME%' {\n" - L" AsynchronousInterface = s '%ASYNC_IID%'\n" - L" }\n" - L" }\n" - L" }\n" - L" }\n" - L"}\n"; - - - -// This fixture assists in launching a sub-process to invoke on our executor. -// We can't do this from another thread in this process because of a bug -// in the COM marshaling machinery that causes an access violation after -// an asynchronous invocation across single-threaded apartments in the -// same process. -class ExecutorComInvocationTest: public ExecutorComTest { - public: - // We register in HKCU if the user is non-admin, otherwise in - // HKLM, because on UAC-enabled systems, HKCU is ignored for - // administrative users. - ExecutorComInvocationTest() - : root_key_(::IsUserAnAdmin() ? L"HKLM" : L"HKCU"), - clsid_(GUID_NULL), - cookie_(0), - invoker_(base::kNullProcessHandle) { - } - - void UpdateRegistry(bool reg) { - // Register or unregister the sync->async IID mapping in our HKCR. - // Unfortunately there's no way to do this without changing machine-global - // state. The COM marshaling machinery does lookups in HKCR, which seems - // to be amalgamated from HKCU and HKLM in kernel-land, so - // RegOverridePredefKey doesn't help. - CRegObject reg_obj; - ASSERT_HRESULT_SUCCEEDED(reg_obj.FinalConstruct()); - ASSERT_HRESULT_SUCCEEDED( - reg_obj.AddReplacement(L"IID", CComBSTR(IID_ICeeeTabExecutor))); - ASSERT_HRESULT_SUCCEEDED( - reg_obj.AddReplacement(L"ASYNC_IID", - CComBSTR(IID_AsyncICeeeTabExecutor))); - ASSERT_HRESULT_SUCCEEDED( - reg_obj.AddReplacement(L"NAME", L"ICeeeTabExecutor")); - ASSERT_HRESULT_SUCCEEDED( - reg_obj.AddReplacement(L"ROOT", root_key_)); - - if (reg) { - ASSERT_HRESULT_SUCCEEDED(reg_obj.StringRegister(kRegScript)); - } else { - ASSERT_HRESULT_SUCCEEDED(reg_obj.StringUnregister(kRegScript)); - } - } - - virtual void SetUp() { - ASSERT_NO_FATAL_FAILURE(ExecutorComTest::SetUp()); - ASSERT_NO_FATAL_FAILURE(UpdateRegistry(true)); - ASSERT_NO_FATAL_FAILURE(RegisterProxies()); - - // Register a class factory with a new clsid. - ASSERT_HRESULT_SUCCEEDED(::CoCreateGuid(&clsid_)); - ASSERT_HRESULT_SUCCEEDED( - TestClassFactory::CreateInitialized(executor_, &class_factory_)); - ASSERT_HRESULT_SUCCEEDED(::CoRegisterClassObject(clsid_, - class_factory_, - CLSCTX_LOCAL_SERVER, - REGCLS_MULTIPLEUSE, - &cookie_)); - } - - virtual void TearDown() { - // Wait for the invoker and assert it returned E_CAFEBABE. - if (invoker_ != base::kNullProcessHandle) { - int exit_code = -1; - EXPECT_TRUE(base::WaitForExitCode(invoker_, &exit_code)); - EXPECT_EQ(E_CAFEBABE, exit_code); - } - - EXPECT_HRESULT_SUCCEEDED(::CoRevokeClassObject(cookie_)); - EXPECT_NO_FATAL_FAILURE(UpdateRegistry(false)); - ExecutorComTest::TearDown(); - } - - template <size_t N> - void InvokeExecutor(const char* func, const char* (&args)[N]) { - FilePath testing_invoke_executor; - ASSERT_TRUE(PathService::Get(base::DIR_EXE, &testing_invoke_executor)); - testing_invoke_executor = - testing_invoke_executor.Append(L"testing_invoke_executor.exe"); - - wchar_t clsid_str[40] = {}; - ASSERT_NE(0, ::StringFromGUID2(clsid_, clsid_str, arraysize(clsid_str))); - CommandLine cmd_line(testing_invoke_executor); - cmd_line.AppendSwitchNative("class_id", clsid_str); - cmd_line.AppendSwitchASCII("func", func); - - ASSERT_TRUE(N % 2 == 0); - for (size_t i = 0; i < N; i += 2) { - cmd_line.AppendSwitchASCII(args[i], args[i + 1]); - } - - ASSERT_TRUE(base::LaunchApp(cmd_line, false, true, &invoker_)); - } - - protected: - GUID clsid_; - DWORD cookie_; - CComPtr<IClassFactory> class_factory_; - const wchar_t* root_key_; - base::ProcessHandle invoker_; -}; - - -TEST_F(ExecutorComInvocationTest, SyncInitialize) { - const char* args[] = { - "hwnd", "1457", - }; - ASSERT_NO_FATAL_FAILURE(InvokeExecutor("Initialize", args)); - - { - InSequence sequence; - - // We expect the invocation to do a create tab call, - // followed by a navigate. - ExpectCreateTabCall(executor_); - EXPECT_CALL(*executor_, Initialize(static_cast<CeeeWindowHandle>(1457))) - .WillOnce( - DoAll( - QuitMessageLoop(&loop_), - Return(E_CAFEBABE))); - } - - loop_.Run(); -} - -TEST_F(ExecutorComInvocationTest, AsyncGetTabInfo) { - const char* args[] = { - "ignore", "me", - }; - ASSERT_NO_FATAL_FAILURE(InvokeExecutor("GetTabInfo", args)); - - { - InSequence sequence; - - // We expect the invocation to do a create tab call, - // followed by a navigate. - ExpectCreateTabCall(executor_); - EXPECT_CALL(*executor_, GetTabInfo(NotNull())) - .WillOnce( - DoAll( - QuitMessageLoop(&loop_), - Return(E_CAFEBABE))); - } - - loop_.Run(); -} - -TEST_F(ExecutorComInvocationTest, AsyncNavigate) { - const char* args[] = { - "url", "http://www.google.com/", - "flags", "74565", - "target", "_blank", - }; - ASSERT_NO_FATAL_FAILURE(InvokeExecutor("Navigate", args)); - - { - InSequence sequence; - - // We expect the invocation to do a create tab call, - // followed by a navigate. - ExpectCreateTabCall(executor_); - EXPECT_CALL(*executor_, Navigate(StrEq(L"http://www.google.com/"), - kFlags, - StrEq(kTarget))) - .WillOnce( - DoAll( - QuitMessageLoop(&loop_), - Return(E_CAFEBABE))); - } - - loop_.Run(); -} - -TEST_F(ExecutorComInvocationTest, AsyncInsertCode) { - const char* args[] = { - "code", "alert('you\'ve been had')", - "file", "CONSOLE", - "all_frames", "true", - "type", "1", // kCeeeTabCodeTypeJs - }; - ASSERT_NO_FATAL_FAILURE(InvokeExecutor("InsertCode", args)); - - { - InSequence sequence; - - // We expect the invocation to do a create tab call, - // followed by a navigate. - ExpectCreateTabCall(executor_); - EXPECT_CALL(*executor_, InsertCode(StrEq(L"alert('you\'ve been had')"), - StrEq(L"CONSOLE"), - TRUE, - kCeeeTabCodeTypeJs)) - .WillOnce( - DoAll( - QuitMessageLoop(&loop_), - Return(E_CAFEBABE))); - } - - loop_.Run(); -} - -} // namespace diff --git a/ceee/ie/plugin/bho/testing_invoke_executor.cc b/ceee/ie/plugin/bho/testing_invoke_executor.cc deleted file mode 100644 index f56de47..0000000 --- a/ceee/ie/plugin/bho/testing_invoke_executor.cc +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2010 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. -// -// Implements a command-line executable that assists in testing the executor -// by invoking on it from across a process boundary. -#include <atlbase.h> -#include <string> -#include "base/at_exit.h" -#include "base/command_line.h" -#include "base/logging.h" -#include "ceee/ie/plugin/toolband/toolband_proxy.h" - -#include "toolband.h" // NOLINT - -HRESULT DoInitialize(ICeeeTabExecutor* executor, CommandLine* cmd_line) { - CeeeWindowHandle hwnd = static_cast<CeeeWindowHandle>( - atoi(cmd_line->GetSwitchValueASCII("hwnd").c_str())); - - return executor->Initialize(hwnd); -} - -HRESULT DoGetTabInfo(ICeeeTabExecutor* executor, CommandLine* cmd_line) { - CeeeTabInfo info = {}; - return executor->GetTabInfo(&info); -} - -HRESULT DoNavigate(ICeeeTabExecutor* executor, CommandLine* cmd_line) { - std::wstring url = cmd_line->GetSwitchValueNative("url"); - long flags = atoi(cmd_line->GetSwitchValueASCII("flags").c_str()); - std::wstring target = cmd_line->GetSwitchValueNative("target"); - - return executor->Navigate(CComBSTR(url.c_str()), - flags, - CComBSTR(target.c_str())); -} - -HRESULT DoInsertCode(ICeeeTabExecutor* executor, CommandLine* cmd_line) { - std::wstring code = cmd_line->GetSwitchValueNative("code"); - std::wstring file = cmd_line->GetSwitchValueNative("file"); - bool all_frames = cmd_line->GetSwitchValueASCII("all_frames") == "true"; - CeeeTabCodeType type = static_cast<CeeeTabCodeType>( - atoi(cmd_line->GetSwitchValueASCII("type").c_str())); - - return executor->InsertCode(CComBSTR(code.c_str()), - CComBSTR(file.c_str()), - all_frames, - type); -} - -int main(int argc, char** argv) { - ::CoInitialize(NULL); - - base::AtExitManager at_exit; - CommandLine::Init(argc, argv); - - CommandLine* cmd_line = CommandLine::ForCurrentProcess(); - std::wstring clsid = cmd_line->GetSwitchValueNative("class_id"); - - // Register the proxy/stubs for the exector interfaces. - RegisterProxyStubs(NULL); - - CLSID executor_clsid = {}; - HRESULT hr = ::CLSIDFromString(clsid.c_str(), &executor_clsid); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to read class_id argument"; - exit(hr); - } - - CComPtr<ICeeeTabExecutor> executor; - hr = executor.CoCreateInstance(executor_clsid); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create tab executor."; - exit(hr); - } - - std::string func = cmd_line->GetSwitchValueASCII("func"); - if (func == "Initialize") { - hr = DoInitialize(executor, cmd_line); - } else if (func == "GetTabInfo") { - hr = DoGetTabInfo(executor, cmd_line); - } else if (func == "Navigate") { - hr = DoNavigate(executor, cmd_line); - } else if (func == "InsertCode") { - hr = DoInsertCode(executor, cmd_line); - } else { - hr = E_UNEXPECTED; - } - - // We exit, because we don't want to trust the - // server to be around for teardown and goodbyes. - exit(hr); - - NOTREACHED(); - return hr; -} diff --git a/ceee/ie/plugin/toolband/resource.h b/ceee/ie/plugin/toolband/resource.h index 1d27001..d090e40 100644 --- a/ceee/ie/plugin/toolband/resource.h +++ b/ceee/ie/plugin/toolband/resource.h @@ -18,7 +18,7 @@ #define IDR_GREASEMONKEY_API_JS 105 #define IDR_EXECUTOR 106 #define IDR_EXECUTOR_CREATOR 107 -#define IDR_TOOLBAND_PROXY 108 +#define IDR_NO_EXTENSION 108 // Next default values for new objects // diff --git a/ceee/ie/plugin/toolband/toolband.gyp b/ceee/ie/plugin/toolband/toolband.gyp index 63686f1..7fb5529bfc 100644 --- a/ceee/ie/plugin/toolband/toolband.gyp +++ b/ceee/ie/plugin/toolband/toolband.gyp @@ -41,7 +41,6 @@ '../../broker/broker.gyp:broker_rpc_lib', 'ceee_ie_lib', 'ie_toolband_common', - 'toolband_proxy_lib', 'toolband_idl', '../bho/bho.gyp:bho', '../scripting/scripting.gyp:scripting', @@ -67,8 +66,8 @@ '../scripting/content_script_manager.rc', ], 'libraries': [ - 'iepmapi.lib', 'oleacc.lib', + 'iepmapi.lib', 'rpcrt4.lib', ], 'include_dirs': [ @@ -121,32 +120,5 @@ 'include_dirs': ['<(SHARED_INTERMEDIATE_DIR)'], }, }, - { - # This target builds a library out of the toolband proxy/stubs. - # TODO(siggi): Rename the IDL and move it to ie/plugin/common, as - # it's defining interfaces that are common across the the broker - # and bho/executor. - 'target_name': 'toolband_proxy_lib', - 'type': 'static_library', - 'sources': [ - 'toolband_proxy.h', - 'toolband_proxy.cc', - 'toolband_proxy.rgs', - '<(SHARED_INTERMEDIATE_DIR)/toolband_p.c', - '<(SHARED_INTERMEDIATE_DIR)/toolband_dlldata.c', - ], - 'dependencies': [ - '../../../../base/base.gyp:base', - 'toolband_idl', - ], - 'defines': [ - # This define adds ToolbandProxy as a prefix to the generated - # proxy/stub entrypoint routine names. - 'ENTRY_PREFIX=ToolbandProxy', - # The proxy stub code defines _purecall, which conflicts with our - # CRT, so we neuter this here. - '_purecall=ToolbandPureCall', - ], - }, ] } diff --git a/ceee/ie/plugin/toolband/toolband.idl b/ceee/ie/plugin/toolband/toolband.idl index f85fff9..4164945 100644 --- a/ceee/ie/plugin/toolband/toolband.idl +++ b/ceee/ie/plugin/toolband/toolband.idl @@ -4,12 +4,6 @@ // // @file // Interface and object declarations for CEEE IE toolband. -// -// Note: We hand-register the proxy/stubs for the marshalable interfaces -// in this file in each COM apartment that needs to use them. -// If you add new marshalable interfaces to this file be sure to update -// the list of interface proxy/stubs in toolband_proxy.cc, and to -// call RegisterProxyStubs and UnregisterProxyStubs appropriately. import "oaidl.idl"; import "ocidl.idl"; @@ -108,10 +102,11 @@ typedef struct { [ object, - uuid(66CDB7E2-B326-493e-B469-16234426C89B), + uuid(8DEEECC5-7B49-482d-99F8-2109EA5F2618), nonextensible, helpstring("ICeeeWindowExecutor Interface"), pointer_default(unique), + oleautomation ] // Object provided to the broker to execute code in a given window's thread. interface ICeeeWindowExecutor : IUnknown { @@ -181,11 +176,11 @@ interface ICeeeWindowExecutor : IUnknown { [ object, - uuid(1F509E26-002A-461b-9083-ABD1002BD4E2), - async_uuid(EDF51257-5A41-4391-8186-44DB3E84FBE6), + uuid(C7FF41BA-72D5-4086-8B5A-2EF4FD12E0FE), nonextensible, helpstring("ICeeeTabExecutor Interface"), pointer_default(unique), + oleautomation ] // Object provided to the broker to execute code in a given window's thread. interface ICeeeTabExecutor : IUnknown { @@ -233,10 +228,11 @@ interface ICeeeTabExecutor : IUnknown { [ object, - uuid(875DB992-6ADA-4330-AD3F-28B3E3B9DB01), + uuid(07630967-D7FB-4745-992F-28614930D9A3), nonextensible, helpstring("ICeeeCookieExecutor Interface"), pointer_default(unique), + oleautomation ] // Object provided to the broker to execute code in a given window's thread. interface ICeeeCookieExecutor : IUnknown { @@ -271,10 +267,11 @@ interface ICeeeCookieExecutor : IUnknown { [ object, - uuid(C79A1479-33F6-419f-970F-2FB3D1388922), + uuid(276D47E8-1692-4a21-907D-948D170E4330), nonextensible, helpstring("ICeeeInfobarExecutor Interface"), pointer_default(unique), + oleautomation ] // Object provided to the broker to execute code in a given window's thread. interface ICeeeInfobarExecutor : IUnknown { diff --git a/ceee/ie/plugin/toolband/toolband.rc b/ceee/ie/plugin/toolband/toolband.rc index 9a70369..d1319c2 100644 --- a/ceee/ie/plugin/toolband/toolband.rc +++ b/ceee/ie/plugin/toolband/toolband.rc @@ -82,7 +82,6 @@ IDR_BROWSERHELPEROBJECT REGISTRY "..\\..\\ceee\\ie\\plugin\\bho\\ IDR_EXECUTOR REGISTRY "..\\..\\ceee\\ie\\plugin\\bho\\executor.rgs" IDR_EXECUTOR_CREATOR REGISTRY "..\\..\\ceee\\ie\\plugin\\bho\\executor_creator.rgs" IDR_TOOL_BAND REGISTRY "tool_band.rgs" -IDR_TOOLBAND_PROXY REGISTRY "toolband_proxy.rgs" ///////////////////////////////////////////////////////////////////////////// // diff --git a/ceee/ie/plugin/toolband/toolband_module.cc b/ceee/ie/plugin/toolband/toolband_module.cc index 6824542..472bd30 100644 --- a/ceee/ie/plugin/toolband/toolband_module.cc +++ b/ceee/ie/plugin/toolband/toolband_module.cc @@ -16,7 +16,6 @@ #include "ceee/ie/plugin/bho/executor.h" #include "ceee/ie/plugin/toolband/toolband_module_reporting.h" #include "ceee/ie/plugin/toolband/tool_band.h" -#include "ceee/ie/plugin/toolband/toolband_proxy.h" #include "ceee/ie/plugin/scripting/script_host.h" #include "ceee/common/windows_constants.h" #include "chrome/common/url_constants.h" @@ -46,8 +45,6 @@ OBJECT_ENTRY_AUTO(CLSID_CeeeExecutor, CeeeExecutor) class ToolbandModule : public CAtlDllModuleT<ToolbandModule> { public: - typedef CAtlDllModuleT<ToolbandModule> Super; - ToolbandModule(); ~ToolbandModule(); @@ -62,11 +59,8 @@ class ToolbandModule : public CAtlDllModuleT<ToolbandModule> { return module_initialized_; } - // We override reg/unregserver to register proxy/stubs. - HRESULT DllRegisterServer(); - HRESULT DllUnregisterServer(); - private: + base::AtExitManager at_exit_; bool module_initialized_; bool crash_reporting_initialized_; @@ -114,7 +108,7 @@ ToolbandModule::~ToolbandModule() { } HRESULT ToolbandModule::DllCanUnloadNow() { - HRESULT hr = Super::DllCanUnloadNow(); + HRESULT hr = CAtlDllModuleT<ToolbandModule>::DllCanUnloadNow(); if (hr == S_OK) Term(); return hr; @@ -123,26 +117,7 @@ HRESULT ToolbandModule::DllCanUnloadNow() { HRESULT ToolbandModule::DllGetClassObject(REFCLSID clsid, REFIID iid, void** object) { Init(); - return Super::DllGetClassObject(clsid, iid, object); -} - -HRESULT ToolbandModule::DllRegisterServer() { - // No typelib registration. - HRESULT hr = Super::DllRegisterServer(); - if (SUCCEEDED(hr) && !RegisterAsyncProxies(true)) { - hr = SELFREG_E_CLASS; - } - return hr; -} - -HRESULT ToolbandModule::DllUnregisterServer() { - // No typelib registration. - HRESULT hr = Super::DllUnregisterServer(FALSE); - if (!RegisterAsyncProxies(false) && SUCCEEDED(hr)) { - // Note the error. - hr = SELFREG_E_CLASS; - } - return hr; + return CAtlDllModuleT<ToolbandModule>::DllGetClassObject(clsid, iid, object); } void ToolbandModule::Init() { @@ -187,7 +162,8 @@ LONG ceee_module_util::UnlockModule() { return module.Unlock(); } -// DLL Entry Point. + +// DLL Entry Point extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { // Prevent us from being loaded by older versions of the shell. @@ -220,7 +196,7 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { // function, which keeps us safe from ever forgetting to check for // the --enable-ceee flag. STDAPI DllRegisterServerImpl(void) { - // Registers objects. + // registers object, typelib and all interfaces in typelib HRESULT hr = module.DllRegisterServer(); return hr; } diff --git a/ceee/ie/plugin/toolband/toolband_proxy.cc b/ceee/ie/plugin/toolband/toolband_proxy.cc deleted file mode 100644 index 7c1d2f1..0000000 --- a/ceee/ie/plugin/toolband/toolband_proxy.cc +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) 2010 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 "ceee/ie/plugin/toolband/toolband_proxy.h" - -#include <atlbase.h> -#include "base/logging.h" -#include "base/stringprintf.h" -#include "base/win/registry.h" -#include "ceee/common/com_utils.h" -#include "ceee/ie/plugin/toolband/resource.h" - -#include "toolband.h" // NOLINT - -extern "C" { -// Declare the entrypoint function(s) generated by MIDL for our proxy/stubs. -HRESULT STDAPICALLTYPE ToolbandProxyDllGetClassObject(REFCLSID clsid, - REFIID iid, - void** ppv); -} // extern "C" - -namespace { - -struct InterfaceInfo { - const wchar_t* name; - const IID* iid; - const IID* async_iid; -}; - -#define DECLARE_SYNC_INTERFACE(itf) \ - { L#itf, &IID_##itf, NULL }, -#define DECLARE_ASYNC_INTERFACE(itf) \ - { L#itf, &IID_##itf, &IID_Async##itf }, \ - DECLARE_SYNC_INTERFACE(Async##itf) - -// If you add new executor interfaces to toolband.idl, make sure to add -// their IIDs here, or you will not be able to marshal them. -const InterfaceInfo kInterfaceInfo[] = { - DECLARE_SYNC_INTERFACE(ICeeeWindowExecutor) - DECLARE_ASYNC_INTERFACE(ICeeeTabExecutor) - DECLARE_SYNC_INTERFACE(ICeeeCookieExecutor) - DECLARE_SYNC_INTERFACE(ICeeeInfobarExecutor) -}; - -#ifndef NDEBUG -void CheckAsyncIidRegistered(const IID& iid, const IID& async_iid) { - std::wstring iid_str; - bool success = com::GuidToString(iid, &iid_str); - DCHECK(success); - std::wstring key_name = base::StringPrintf( - L"Interface\\%ls\\AsynchronousInterface", iid_str); - - base::win::RegKey key; - if (key.Open(HKEY_CLASSES_ROOT, key_name.c_str(), KEY_READ)) { - // It's registered, the rest of this block is debug checking that - // the correct IID is indeed registered for the async interface. - std::wstring async_iid_str; - DCHECK(key.ReadValue(NULL, &async_iid_str)); - IID read_async_iid; - DCHECK(SUCCEEDED(::IIDFromString(async_iid_str.c_str(), &read_async_iid))); - DCHECK(read_async_iid == async_iid); - } else { - LOG(WARNING) << "Sync->Async IID not registered. Key=" << key_name; - } -} -#endif // NDEBUG - -} // namespace - -bool RegisterProxyStubs(std::vector<DWORD>* cookies) { - bool succeeded = true; - - for (size_t i = 0; i < arraysize(kInterfaceInfo); ++i) { - CComPtr<IUnknown> factory; - const InterfaceInfo& info = kInterfaceInfo[i]; - HRESULT hr = ToolbandProxyDllGetClassObject(*info.iid, IID_IUnknown, - reinterpret_cast<void**>(&factory)); - - DWORD cookie = 0; - if (SUCCEEDED(hr)) { - hr = ::CoRegisterClassObject(*info.iid, factory, CLSCTX_INPROC_SERVER, - REGCLS_MULTIPLEUSE, &cookie); - } - if (SUCCEEDED(hr)) { - // Proxy/stubs have their own IID as class id. - hr = ::CoRegisterPSClsid(*info.iid, *info.iid); - if (SUCCEEDED(hr) && cookies != NULL) { - cookies->push_back(cookie); - } - } - -#ifndef NDEBUG - // If there's a corresponding Async interface, check whether - // it's registered. This is a debugging aid only. - if (info.async_iid != NULL) - CheckAsyncIidRegistered(*info.iid, *info.async_iid); -#endif // NDEBUG - - if (FAILED(hr)) { - succeeded = false; - LOG(ERROR) << "Failed to register proxy " << com::LogHr(hr); - } - } - - VLOG(1) << "Registered toolband proxy/stubs in thread " - << ::GetCurrentThreadId(); - - return succeeded; -} - -void UnregisterProxyStubs(const std::vector<DWORD>& cookies) { - for (size_t i = 0; i < cookies.size(); ++i) { - HRESULT hr = ::CoRevokeClassObject(cookies[i]); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to revoke class object " << com::LogHr(hr); - } - } -} - -bool RegisterAsyncProxies(bool reg) { - for (size_t i = 0; i < arraysize(kInterfaceInfo); ++i) { - // Register the iid->async iid mapping for async interfaces. - if (kInterfaceInfo[i].async_iid != NULL) { - const InterfaceInfo& info = kInterfaceInfo[i]; - std::wstring iid_str; - bool success = com::GuidToString(*info.iid, &iid_str); - DCHECK(success) << "Failed to stringify GUID"; - std::wstring async_iid_str; - success = com::GuidToString(*info.async_iid, &async_iid_str); - DCHECK(success) << "Failed to stringify GUID"; - - _ATL_REGMAP_ENTRY entries[] = { - { L"IID", iid_str.c_str() }, - { L"ASYNC_IID", async_iid_str.c_str() }, - { L"NAME", info.name }, - { NULL, NULL }, - }; - - HRESULT hr = _pAtlModule->UpdateRegistryFromResource( - MAKEINTRESOURCE(IDR_TOOLBAND_PROXY), reg, entries); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to register async interface for " << - info.name << com::LogHr(hr); - return false; - } - } - } - - return true; -} diff --git a/ceee/ie/plugin/toolband/toolband_proxy.h b/ceee/ie/plugin/toolband/toolband_proxy.h deleted file mode 100644 index bbc2314..0000000 --- a/ceee/ie/plugin/toolband/toolband_proxy.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2010 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 CEEE_IE_PLUGIN_TOOLBAND_TOOLBAND_PROXY_H_ -#define CEEE_IE_PLUGIN_TOOLBAND_TOOLBAND_PROXY_H_ - -#include <windows.h> -#include <vector> - -// Registers all proxy/stubs in the current apartment. -// @param cookies if not NULL, then on return contains the registration -// cookies for all successful proxy/stub class object registrations. -// @returns true on success, false on failure. -// @note this function logs errors for all failures. -// @note this function will also create registry entries for the sync/async -// interface mapping for interfaces that have asynchronous variants. -bool RegisterProxyStubs(std::vector<DWORD>* cookies); - -// Unregisters proxy/stub class objects from this apartment. -// @param cookies the cookies returned from an earlier call to -// RegisterProxyStubs in this apartment. -void UnregisterProxyStubs(const std::vector<DWORD>& cookies); - -// Registers or unregisters the sync to async IID mapping in registry -// for any asynchronous interfaces we implement. -// @param reg true to register, false to unregister. -bool RegisterAsyncProxies(bool reg); - -#endif // CEEE_IE_PLUGIN_TOOLBAND_TOOLBAND_PROXY_H_ diff --git a/ceee/ie/plugin/toolband/toolband_proxy.rgs b/ceee/ie/plugin/toolband/toolband_proxy.rgs deleted file mode 100644 index e6bbf04..0000000 --- a/ceee/ie/plugin/toolband/toolband_proxy.rgs +++ /dev/null @@ -1,11 +0,0 @@ -HKLM { - NoRemove Software { - NoRemove Classes { - NoRemove 'Interface' { - '%IID%' = s '%NAME%' { - AsynchronousInterface = s '%ASYNC_IID%' - } - } - } - } -} |