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