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 33 using namespace WebCore; 34 35 // FIXME: move this enum to a separate header file when other code begins to use it. 36 typedef enum WebExtraNavigationType { 37 WebNavigationTypePlugInRequest = WebNavigationTypeOther + 1 38 } WebExtraNavigationType; 39 40 // DefaultPolicyDelegate ---------------------------------------------------------------- 41 42 DefaultPolicyDelegate::DefaultPolicyDelegate() 43 : m_refCount(0) 44 { 45 gClassCount++; 46 gClassNameCount.add("DefaultPolicyDelegate"); 47 } 48 49 DefaultPolicyDelegate::~DefaultPolicyDelegate() 50 { 51 gClassCount--; 52 gClassNameCount.remove("DefaultPolicyDelegate"); 53 } 54 55 DefaultPolicyDelegate* DefaultPolicyDelegate::sharedInstance() 56 { 57 static COMPtr<DefaultPolicyDelegate> shared; 58 if (!shared) 59 shared.adoptRef(DefaultPolicyDelegate::createInstance()); 60 return shared.get(); 61 } 62 63 DefaultPolicyDelegate* DefaultPolicyDelegate::createInstance() 64 { 65 DefaultPolicyDelegate* instance = new DefaultPolicyDelegate(); 66 instance->AddRef(); 67 return instance; 68 } 69 70 // IUnknown ------------------------------------------------------------------- 71 72 HRESULT 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 86 ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::AddRef() 87 { 88 return ++m_refCount; 89 } 90 91 ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::Release() 92 { 93 ULONG newRef = --m_refCount; 94 if (!newRef) 95 delete(this); 96 97 return newRef; 98 } 99 100 HRESULT 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 135 HRESULT 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 146 HRESULT 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 180 HRESULT 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