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
DefaultPolicyDelegate()45 DefaultPolicyDelegate::DefaultPolicyDelegate()
46 : m_refCount(0)
47 {
48 gClassCount++;
49 gClassNameCount.add("DefaultPolicyDelegate");
50 }
51
~DefaultPolicyDelegate()52 DefaultPolicyDelegate::~DefaultPolicyDelegate()
53 {
54 gClassCount--;
55 gClassNameCount.remove("DefaultPolicyDelegate");
56 }
57
sharedInstance()58 DefaultPolicyDelegate* DefaultPolicyDelegate::sharedInstance()
59 {
60 static COMPtr<DefaultPolicyDelegate> shared;
61 if (!shared)
62 shared.adoptRef(DefaultPolicyDelegate::createInstance());
63 return shared.get();
64 }
65
createInstance()66 DefaultPolicyDelegate* DefaultPolicyDelegate::createInstance()
67 {
68 DefaultPolicyDelegate* instance = new DefaultPolicyDelegate();
69 instance->AddRef();
70 return instance;
71 }
72
73 // IUnknown -------------------------------------------------------------------
74
QueryInterface(REFIID riid,void ** ppvObject)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
AddRef()89 ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::AddRef()
90 {
91 return ++m_refCount;
92 }
93
Release()94 ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::Release()
95 {
96 ULONG newRef = --m_refCount;
97 if (!newRef)
98 delete(this);
99
100 return newRef;
101 }
102
decidePolicyForNavigationAction(IWebView * webView,IPropertyBag * actionInformation,IWebURLRequest * request,IWebFrame *,IWebPolicyDecisionListener * listener)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
decidePolicyForNewWindowAction(IWebView *,IPropertyBag *,IWebURLRequest *,BSTR,IWebPolicyDecisionListener * listener)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
decidePolicyForMIMEType(IWebView * webView,BSTR type,IWebURLRequest * request,IWebFrame *,IWebPolicyDecisionListener * listener)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
unableToImplementPolicyWithError(IWebView *,IWebError * error,IWebFrame * frame)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