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 "WebKit.h" 31 32#pragma warning(push, 0) 33#include <WebCore/PlatformString.h> 34#pragma warning(pop) 35 36using namespace WebCore; 37 38// FIXME: move this enum to a separate header file when other code begins to use it. 39typedef enum WebExtraNavigationType { 40 WebNavigationTypePlugInRequest = WebNavigationTypeOther + 1 41} WebExtraNavigationType; 42 43// DefaultPolicyDelegate ---------------------------------------------------------------- 44 45DefaultPolicyDelegate::DefaultPolicyDelegate() 46 : m_refCount(0) 47{ 48 gClassCount++; 49 gClassNameCount.add("DefaultPolicyDelegate"); 50} 51 52DefaultPolicyDelegate::~DefaultPolicyDelegate() 53{ 54 gClassCount--; 55 gClassNameCount.remove("DefaultPolicyDelegate"); 56} 57 58DefaultPolicyDelegate* DefaultPolicyDelegate::sharedInstance() 59{ 60 static COMPtr<DefaultPolicyDelegate> shared; 61 if (!shared) 62 shared.adoptRef(DefaultPolicyDelegate::createInstance()); 63 return shared.get(); 64} 65 66DefaultPolicyDelegate* DefaultPolicyDelegate::createInstance() 67{ 68 DefaultPolicyDelegate* instance = new DefaultPolicyDelegate(); 69 instance->AddRef(); 70 return instance; 71} 72 73// IUnknown ------------------------------------------------------------------- 74 75HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::QueryInterface(REFIID riid, void** ppvObject) 76{ 77 *ppvObject = 0; 78 if (IsEqualGUID(riid, IID_IUnknown)) 79 *ppvObject = static_cast<IUnknown*>(this); 80 else if (IsEqualGUID(riid, IID_IWebPolicyDelegate)) 81 *ppvObject = static_cast<IWebPolicyDelegate*>(this); 82 else 83 return E_NOINTERFACE; 84 85 AddRef(); 86 return S_OK; 87} 88 89ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::AddRef() 90{ 91 return ++m_refCount; 92} 93 94ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::Release() 95{ 96 ULONG newRef = --m_refCount; 97 if (!newRef) 98 delete(this); 99 100 return newRef; 101} 102 103HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForNavigationAction( 104 /*[in]*/ IWebView* webView, 105 /*[in]*/ IPropertyBag* actionInformation, 106 /*[in]*/ IWebURLRequest* request, 107 /*[in]*/ IWebFrame* /*frame*/, 108 /*[in]*/ IWebPolicyDecisionListener* listener) 109{ 110 int navType = 0; 111 VARIANT var; 112 if (SUCCEEDED(actionInformation->Read(WebActionNavigationTypeKey, &var, 0))) { 113 V_VT(&var) = VT_I4; 114 navType = V_I4(&var); 115 } 116 COMPtr<IWebViewPrivate> wvPrivate(Query, webView); 117 if (wvPrivate) { 118 BOOL canHandleRequest = FALSE; 119 if (SUCCEEDED(wvPrivate->canHandleRequest(request, &canHandleRequest)) && canHandleRequest) 120 listener->use(); 121 else if (navType == WebNavigationTypePlugInRequest) 122 listener->use(); 123 else { 124 BSTR url; 125 // A file URL shouldn't fall through to here, but if it did, 126 // it would be a security risk to open it. 127 if (SUCCEEDED(request->URL(&url)) && !String(url, SysStringLen(url)).startsWith("file:")) { 128 // 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] 129 ; 130 } 131 listener->ignore(); 132 SysFreeString(url); 133 } 134 } 135 return S_OK; 136} 137 138HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForNewWindowAction( 139 /*[in]*/ IWebView* /*webView*/, 140 /*[in]*/ IPropertyBag* /*actionInformation*/, 141 /*[in]*/ IWebURLRequest* /*request*/, 142 /*[in]*/ BSTR /*frameName*/, 143 /*[in]*/ IWebPolicyDecisionListener* listener) 144{ 145 listener->use(); 146 return S_OK; 147} 148 149HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForMIMEType( 150 /*[in]*/ IWebView* webView, 151 /*[in]*/ BSTR type, 152 /*[in]*/ IWebURLRequest* request, 153 /*[in]*/ IWebFrame* /*frame*/, 154 /*[in]*/ IWebPolicyDecisionListener* listener) 155{ 156 BOOL canShowMIMEType; 157 if (FAILED(webView->canShowMIMEType(type, &canShowMIMEType))) 158 canShowMIMEType = FALSE; 159 160 BSTR url; 161 request->URL(&url); 162 163 if (String(url, SysStringLen(url)).startsWith("file:")) { 164 BOOL isDirectory = FALSE; 165 WIN32_FILE_ATTRIBUTE_DATA attrs; 166 if (GetFileAttributesEx(url, GetFileExInfoStandard, &attrs)) 167 isDirectory = !!(attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); 168 169 if (isDirectory) 170 listener->ignore(); 171 else if(canShowMIMEType) 172 listener->use(); 173 else 174 listener->ignore(); 175 } else if (canShowMIMEType) 176 listener->use(); 177 else 178 listener->ignore(); 179 SysFreeString(url); 180 return S_OK; 181} 182 183HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::unableToImplementPolicyWithError( 184 /*[in]*/ IWebView* /*webView*/, 185 /*[in]*/ IWebError* error, 186 /*[in]*/ IWebFrame* frame) 187{ 188 BSTR errorStr; 189 error->localizedDescription(&errorStr); 190 191 BSTR frameName; 192 frame->name(&frameName); 193 194 LOG_ERROR("called unableToImplementPolicyWithError:%S inFrame:%S", errorStr ? errorStr : TEXT(""), frameName ? frameName : TEXT("")); 195 SysFreeString(errorStr); 196 SysFreeString(frameName); 197 198 return S_OK; 199} 200