diff options
author | slightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-24 05:11:58 +0000 |
---|---|---|
committer | slightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-24 05:11:58 +0000 |
commit | f781782dd67077478e117c61dca4ea5eefce3544 (patch) | |
tree | 4801f724123cfdcbb69c4e7fe40a565b331723ae /chrome_frame/protocol_sink_wrap.h | |
parent | 63cf4759efa2373e33436fb5df6849f930081226 (diff) | |
download | chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.zip chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.gz chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.bz2 |
Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming in a separate CL.
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/218019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/protocol_sink_wrap.h')
-rw-r--r-- | chrome_frame/protocol_sink_wrap.h | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/chrome_frame/protocol_sink_wrap.h b/chrome_frame/protocol_sink_wrap.h new file mode 100644 index 0000000..e4f9cfb --- /dev/null +++ b/chrome_frame/protocol_sink_wrap.h @@ -0,0 +1,221 @@ +// 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_PROTOCOL_SINK_WRAP_H_ +#define CHROME_FRAME_PROTOCOL_SINK_WRAP_H_ + +#include <exdisp.h> +#include <urlmon.h> +#include <atlbase.h> +#include <atlcom.h> +#include <map> +#include <string> + +#include "base/basictypes.h" +#include "base/ref_counted.h" +#include "base/scoped_comptr_win.h" +#include "googleurl/src/gurl.h" +#include "chrome_frame/ie8_types.h" + +// Typedefs for IInternetProtocol and related methods that we patch. +typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Start_Fn)( + IInternetProtocol* this_object, LPCWSTR url, + IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info, + DWORD flags, HANDLE_PTR reserved); +typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_Read_Fn)( + IInternetProtocol* this_object, void* buffer, ULONG size, + ULONG* size_read); +typedef HRESULT (STDMETHODCALLTYPE* InternetProtocol_StartEx_Fn)( + IInternetProtocolEx* this_object, IUri* uri, + IInternetProtocolSink* prot_sink, IInternetBindInfo* bind_info, + DWORD flags, HANDLE_PTR reserved); +typedef HRESULT (STDMETHODCALLTYPE* InternetProtocolRoot_Continue_Fn)( + IInternetProtocolRoot* me, PROTOCOLDATA* data); + +// A class to wrap protocol sink in IInternetProtocol::Start[Ex] for +// HTTP and HTTPS protocols. +// +// This is an alternative to a mime filter and we have to do this in order +// to inspect initial portion of HTML for 'chrome' meta tag and report +// a different mime type in that case. +// +// We implement several documented interfaces +// supported by the original sink provided by urlmon. There are a few +// undocumented interfaces that we have chosen not to implement +// but delegate simply the QI. +class ProtocolSinkWrap + : public CComObjectRootEx<CComMultiThreadModel>, + public IInternetProtocolSink, + public IInternetBindInfoEx, + public IServiceProvider, + public IAuthenticate, + public IInternetProtocolEx, + public IInternetPriority, + public IWrappedProtocol, + // public IPreBindingSupport, // undocumented + // public ITransProtocolSink, // Undocumented + // public ITransactionInternal, // undocumented + 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) + COM_INTERFACE_ENTRY(IInternetBindInfoEx) + COM_INTERFACE_ENTRY(IServiceProvider) + COM_INTERFACE_ENTRY(IAuthenticate) + COM_INTERFACE_ENTRY(IInternetProtocolRoot) + COM_INTERFACE_ENTRY(IInternetProtocol) + COM_INTERFACE_ENTRY(IInternetProtocolEx) + COM_INTERFACE_ENTRY(IInternetPriority) + COM_INTERFACE_ENTRY(IWrappedProtocol) + COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS(IUriContainer) + COM_INTERFACE_ENTRY_FUNC_BLIND(0, CheckOutgoingInterface) +END_COM_MAP() + + ProtocolSinkWrap(); + virtual ~ProtocolSinkWrap(); + + bool Initialize(IInternetProtocol* protocol, + IInternetProtocolSink* original_sink, const wchar_t* url); + + static bool PatchProtocolHandler(const wchar_t* dll, + const CLSID& handler_clsid); + + // IInternetProtocol/Ex patches. + static HRESULT STDMETHODCALLTYPE 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( + 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, + IInternetProtocol* protocol, void* buffer, ULONG size, ULONG* size_read); + + // IInternetProtocolSink methods + STDMETHOD(Switch)(PROTOCOLDATA* protocol_data); + STDMETHOD(ReportProgress)(ULONG status_code, LPCWSTR status_text); + STDMETHOD(ReportData)(DWORD flags, ULONG progress, ULONG max_progress); + STDMETHOD(ReportResult)(HRESULT result, DWORD error, LPCWSTR result_text); + + // IInternetBindInfoEx + STDMETHOD(GetBindInfo)(DWORD* flags, BINDINFO* bind_info); + STDMETHOD(GetBindString)(ULONG string_type, LPOLESTR* string_array, + ULONG array_size, ULONG* size_returned); + STDMETHOD(GetBindInfoEx)(DWORD *flags, BINDINFO* bind_info, + DWORD* bindf2, DWORD *reserved); + + // IServiceProvider + STDMETHOD(QueryService)(REFGUID service_guid, REFIID riid, void** service); + + // IAuthenticate + STDMETHOD(Authenticate)(HWND* window, LPWSTR* user_name, LPWSTR* password); + + // IInternetProtocolEx + STDMETHOD(Start)(LPCWSTR url, IInternetProtocolSink *protocol_sink, + IInternetBindInfo* bind_info, DWORD flags, HANDLE_PTR reserved); + STDMETHOD(Continue)(PROTOCOLDATA* protocol_data); + STDMETHOD(Abort)(HRESULT reason, DWORD options); + STDMETHOD(Terminate)(DWORD options); + STDMETHOD(Suspend)(); + STDMETHOD(Resume)(); + STDMETHOD(Read)(void *buffer, ULONG size, ULONG* size_read); + STDMETHOD(Seek)(LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER* new_pos); + STDMETHOD(LockRequest)(DWORD options); + STDMETHOD(UnlockRequest)(); + STDMETHOD(StartEx)(IUri* uri, IInternetProtocolSink* protocol_sink, + IInternetBindInfo* bind_info, DWORD flags, HANDLE_PTR reserved); + + // IInternetPriority + STDMETHOD(SetPriority)(LONG priority); + STDMETHOD(GetPriority)(LONG* priority); + + // IWrappedProtocol + STDMETHOD(GetWrapperCode)(LONG *code, DWORD_PTR reserved); + + // public IUriContainer + STDMETHOD(GetIUri)(IUri** uri); + + // IPreBindingSupport, // undocumented + // ITransProtocolSink, // Undocumented + // ITransactionInternal, // undocumented + + protected: + enum RendererType { + UNDETERMINED, + CHROME, + OTHER + }; + + typedef std::map<IInternetProtocol*, ProtocolSinkWrap*> ProtocolSinkMap; + static const int kMaxContentSniffLength = 1024; + + static scoped_refptr<ProtocolSinkWrap> InstanceFromProtocol( + IInternetProtocol* protocol); + static HRESULT WebBrowserFromProtocolSink(IInternetProtocolSink* sink, + IWebBrowser2** web_browser); + 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, + InternetProtocol_Read_Fn orig_read); + + bool is_undetermined() const { + return (UNDETERMINED == renderer_type_); + } + RendererType renderer_type() const { + return renderer_type_; + } + + // WARNING: Don't use GURL variables here. Please see + // http://b/issue?id=2102171 for details. + + // Remember original sink + CComPtr<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_; + + // Accumulated result + bool is_saved_result_; + HRESULT result_code_; + DWORD result_error_; + std::wstring result_text_; + // For tracking re-entrency and preventing duplicate Read()s from + // distorting the outcome of ReportData. + int report_data_recursiveness_; + + static ProtocolSinkMap sink_map_; + // TODO(joshia): Replace with Lock + static CComAutoCriticalSection sink_map_lock_; + + std::wstring url_; + + private: + DISALLOW_COPY_AND_ASSIGN(ProtocolSinkWrap); +}; + + +#endif // CHROME_FRAME_PROTOCOL_SINK_WRAP_H_ + |