1/* 2 * Copyright (C) 2007 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "WebKitDLL.h" 28#include "DefaultPolicyDelegate.h" 29 30#include <WebCore/COMPtr.h> 31#include <WebCore/PlatformString.h> 32 33using namespace WebCore; 34 35// FIXME: move this enum to a separate header file when other code begins to use it. 36typedef enum WebExtraNavigationType { 37 WebNavigationTypePlugInRequest = WebNavigationTypeOther + 1 38} WebExtraNavigationType; 39 40// DefaultPolicyDelegate ---------------------------------------------------------------- 41 42DefaultPolicyDelegate::DefaultPolicyDelegate() 43 : m_refCount(0) 44{ 45 gClassCount++; 46 gClassNameCount.add("DefaultPolicyDelegate"); 47} 48 49DefaultPolicyDelegate::~DefaultPolicyDelegate() 50{ 51 gClassCount--; 52 gClassNameCount.remove("DefaultPolicyDelegate"); 53} 54 55DefaultPolicyDelegate* DefaultPolicyDelegate::sharedInstance() 56{ 57 static COMPtr<DefaultPolicyDelegate> shared; 58 if (!shared) 59 shared.adoptRef(DefaultPolicyDelegate::createInstance()); 60 return shared.get(); 61} 62 63DefaultPolicyDelegate* DefaultPolicyDelegate::createInstance() 64{ 65 DefaultPolicyDelegate* instance = new DefaultPolicyDelegate(); 66 instance->AddRef(); 67 return instance; 68} 69 70// IUnknown ------------------------------------------------------------------- 71 72HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::QueryInterface(REFIID riid, void** ppvObject) 73{ 74 *ppvObject = 0; 75 if (IsEqualGUID(riid, IID_IUnknown)) 76 *ppvObject = static_cast<IUnknown*>(this); 77 else if (IsEqualGUID(riid, IID_IWebPolicyDelegate)) 78 *ppvObject = static_cast<IWebPolicyDelegate*>(this); 79 else 80 return E_NOINTERFACE; 81 82 AddRef(); 83 return S_OK; 84} 85 86ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::AddRef() 87{ 88 return ++m_refCount; 89} 90 91ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::Release() 92{ 93 ULONG newRef = --m_refCount; 94 if (!newRef) 95 delete(this); 96 97 return newRef; 98} 99 100HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForNavigationAction( 101 /*[in]*/ IWebView* webView, 102 /*[in]*/ IPropertyBag* actionInformation, 103 /*[in]*/ IWebURLRequest* request, 104 /*[in]*/ IWebFrame* /*frame*/, 105 /*[in]*/ IWebPolicyDecisionListener* listener) 106{ 107 int navType = 0; 108 VARIANT var; 109 if (SUCCEEDED(actionInformation->Read(WebActionNavigationTypeKey, &var, 0))) { 110 V_VT(&var) = VT_I4; 111 navType = V_I4(&var); 112 } 113 COMPtr<IWebViewPrivate> wvPrivate(Query, webView); 114 if (wvPrivate) { 115 BOOL canHandleRequest = FALSE; 116 if (SUCCEEDED(wvPrivate->canHandleRequest(request, &canHandleRequest)) && canHandleRequest) 117 listener->use(); 118 else if (navType == WebNavigationTypePlugInRequest) 119 listener->use(); 120 else { 121 BSTR url; 122 // A file URL shouldn't fall through to here, but if it did, 123 // it would be a security risk to open it. 124 if (SUCCEEDED(request->URL(&url)) && !String(url, SysStringLen(url)).startsWith("file:")) { 125 // FIXME: Open the URL not by means of a webframe, but by handing it over to the system and letting it determine how to open that particular URL scheme. See documentation for [NSWorkspace openURL] 126 ; 127 } 128 listener->ignore(); 129 SysFreeString(url); 130 } 131 } 132 return S_OK; 133} 134 135HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForNewWindowAction( 136 /*[in]*/ IWebView* /*webView*/, 137 /*[in]*/ IPropertyBag* /*actionInformation*/, 138 /*[in]*/ IWebURLRequest* /*request*/, 139 /*[in]*/ BSTR /*frameName*/, 140 /*[in]*/ IWebPolicyDecisionListener* listener) 141{ 142 listener->use(); 143 return S_OK; 144} 145 146HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForMIMEType( 147 /*[in]*/ IWebView* webView, 148 /*[in]*/ BSTR type, 149 /*[in]*/ IWebURLRequest* request, 150 /*[in]*/ IWebFrame* /*frame*/, 151 /*[in]*/ IWebPolicyDecisionListener* listener) 152{ 153 BOOL canShowMIMEType; 154 if (FAILED(webView->canShowMIMEType(type, &canShowMIMEType))) 155 canShowMIMEType = FALSE; 156 157 BSTR url; 158 request->URL(&url); 159 160 if (String(url, SysStringLen(url)).startsWith("file:")) { 161 BOOL isDirectory = FALSE; 162 WIN32_FILE_ATTRIBUTE_DATA attrs; 163 if (GetFileAttributesEx(url, GetFileExInfoStandard, &attrs)) 164 isDirectory = !!(attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); 165 166 if (isDirectory) 167 listener->ignore(); 168 else if(canShowMIMEType) 169 listener->use(); 170 else 171 listener->ignore(); 172 } else if (canShowMIMEType) 173 listener->use(); 174 else 175 listener->ignore(); 176 SysFreeString(url); 177 return S_OK; 178} 179 180HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::unableToImplementPolicyWithError( 181 /*[in]*/ IWebView* /*webView*/, 182 /*[in]*/ IWebError* error, 183 /*[in]*/ IWebFrame* frame) 184{ 185 BSTR errorStr; 186 error->localizedDescription(&errorStr); 187 188 BSTR frameName; 189 frame->name(&frameName); 190 191 LOG_ERROR("called unableToImplementPolicyWithError:%S inFrame:%S", errorStr ? errorStr : TEXT(""), frameName ? frameName : TEXT("")); 192 SysFreeString(errorStr); 193 SysFreeString(frameName); 194 195 return S_OK; 196} 197