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 "WebError.h"
29 #include "WebKit.h"
30
31 #pragma warning(push, 0)
32 #include <WebCore/BString.h>
33 #pragma warning(pop)
34
35 #if USE(CFNETWORK)
36 #include <WebKitSystemInterface/WebKitSystemInterface.h>
37 #endif
38
39 using namespace WebCore;
40
41 // WebError ---------------------------------------------------------------------
42
WebError(const ResourceError & error,IPropertyBag * userInfo)43 WebError::WebError(const ResourceError& error, IPropertyBag* userInfo)
44 : m_refCount(0)
45 , m_error(error)
46 , m_userInfo(userInfo)
47 {
48 gClassCount++;
49 gClassNameCount.add("WebError");
50 }
51
~WebError()52 WebError::~WebError()
53 {
54 gClassCount--;
55 gClassNameCount.remove("WebError");
56 }
57
createInstance(const ResourceError & error,IPropertyBag * userInfo)58 WebError* WebError::createInstance(const ResourceError& error, IPropertyBag* userInfo)
59 {
60 WebError* instance = new WebError(error, userInfo);
61 instance->AddRef();
62 return instance;
63 }
64
createInstance()65 WebError* WebError::createInstance()
66 {
67 return createInstance(ResourceError());
68 }
69
70 // IUnknown -------------------------------------------------------------------
71
QueryInterface(REFIID riid,void ** ppvObject)72 HRESULT STDMETHODCALLTYPE WebError::QueryInterface(REFIID riid, void** ppvObject)
73 {
74 *ppvObject = 0;
75 if (IsEqualGUID(riid, IID_IUnknown))
76 *ppvObject = static_cast<IWebError*>(this);
77 else if (IsEqualGUID(riid, CLSID_WebError))
78 *ppvObject = static_cast<WebError*>(this);
79 else if (IsEqualGUID(riid, IID_IWebError))
80 *ppvObject = static_cast<IWebError*>(this);
81 else if (IsEqualGUID(riid, IID_IWebErrorPrivate))
82 *ppvObject = static_cast<IWebErrorPrivate*>(this);
83 else
84 return E_NOINTERFACE;
85
86 AddRef();
87 return S_OK;
88 }
89
AddRef(void)90 ULONG STDMETHODCALLTYPE WebError::AddRef(void)
91 {
92 return ++m_refCount;
93 }
94
Release(void)95 ULONG STDMETHODCALLTYPE WebError::Release(void)
96 {
97 ULONG newRef = --m_refCount;
98 if (!newRef)
99 delete(this);
100
101 return newRef;
102 }
103
104 // IWebError ------------------------------------------------------------------
105
init(BSTR domain,int code,BSTR url)106 HRESULT STDMETHODCALLTYPE WebError::init(
107 /* [in] */ BSTR domain,
108 /* [in] */ int code,
109 /* [in] */ BSTR url)
110 {
111 m_error = ResourceError(String(domain, SysStringLen(domain)), code, String(url, SysStringLen(url)), String());
112 return S_OK;
113 }
114
code(int * result)115 HRESULT STDMETHODCALLTYPE WebError::code(
116 /* [retval][out] */ int* result)
117 {
118 *result = m_error.errorCode();
119 return S_OK;
120 }
121
domain(BSTR * result)122 HRESULT STDMETHODCALLTYPE WebError::domain(
123 /* [retval][out] */ BSTR* result)
124 {
125 if (!result)
126 return E_POINTER;
127
128 *result = BString(m_error.domain()).release();
129 return S_OK;
130 }
131
localizedDescription(BSTR * result)132 HRESULT STDMETHODCALLTYPE WebError::localizedDescription(
133 /* [retval][out] */ BSTR* result)
134 {
135 if (!result)
136 return E_POINTER;
137
138 *result = BString(m_error.localizedDescription()).release();
139
140 #if PLATFORM(CFNETWORK)
141 if (!*result) {
142 if (int code = m_error.errorCode())
143 *result = BString(wkCFNetworkErrorGetLocalizedDescription(code)).release();
144 }
145 #endif
146
147 return S_OK;
148 }
149
150
localizedFailureReason(BSTR *)151 HRESULT STDMETHODCALLTYPE WebError::localizedFailureReason(
152 /* [retval][out] */ BSTR* /*result*/)
153 {
154 ASSERT_NOT_REACHED();
155 return E_NOTIMPL;
156 }
157
localizedRecoveryOptions(IEnumVARIANT **)158 HRESULT STDMETHODCALLTYPE WebError::localizedRecoveryOptions(
159 /* [retval][out] */ IEnumVARIANT** /*result*/)
160 {
161 ASSERT_NOT_REACHED();
162 return E_NOTIMPL;
163 }
164
localizedRecoverySuggestion(BSTR *)165 HRESULT STDMETHODCALLTYPE WebError::localizedRecoverySuggestion(
166 /* [retval][out] */ BSTR* /*result*/)
167 {
168 ASSERT_NOT_REACHED();
169 return E_NOTIMPL;
170 }
171
recoverAttempter(IUnknown **)172 HRESULT STDMETHODCALLTYPE WebError::recoverAttempter(
173 /* [retval][out] */ IUnknown** /*result*/)
174 {
175 ASSERT_NOT_REACHED();
176 return E_NOTIMPL;
177 }
178
userInfo(IPropertyBag ** result)179 HRESULT STDMETHODCALLTYPE WebError::userInfo(
180 /* [retval][out] */ IPropertyBag** result)
181 {
182 if (!result)
183 return E_POINTER;
184 *result = 0;
185
186 if (!m_userInfo)
187 return E_FAIL;
188
189 return m_userInfo.copyRefTo(result);
190 }
191
failingURL(BSTR * result)192 HRESULT STDMETHODCALLTYPE WebError::failingURL(
193 /* [retval][out] */ BSTR* result)
194 {
195 if (!result)
196 return E_POINTER;
197
198 *result = BString(m_error.failingURL()).release();
199 return S_OK;
200 }
201
isPolicyChangeError(BOOL * result)202 HRESULT STDMETHODCALLTYPE WebError::isPolicyChangeError(
203 /* [retval][out] */ BOOL *result)
204 {
205 if (!result)
206 return E_POINTER;
207
208 *result = m_error.domain() == String(WebKitErrorDomain)
209 && m_error.errorCode() == WebKitErrorFrameLoadInterruptedByPolicyChange;
210 return S_OK;
211 }
212
sslPeerCertificate(OLE_HANDLE * result)213 HRESULT STDMETHODCALLTYPE WebError::sslPeerCertificate(
214 /* [retval][out] */ OLE_HANDLE* result)
215 {
216 if (!result)
217 return E_POINTER;
218 *result = 0;
219
220 #if USE(CFNETWORK)
221 if (!m_cfErrorUserInfoDict) {
222 // copy userinfo from CFErrorRef
223 CFErrorRef cfError = m_error;
224 m_cfErrorUserInfoDict.adoptCF(CFErrorCopyUserInfo(cfError));
225 }
226
227 if (!m_cfErrorUserInfoDict)
228 return E_FAIL;
229
230 void* data = wkGetSSLPeerCertificateData(m_cfErrorUserInfoDict.get());
231 if (!data)
232 return E_FAIL;
233 *result = (OLE_HANDLE)(ULONG64)data;
234 #endif
235 return *result ? S_OK : E_FAIL;
236 }
237
resourceError() const238 const ResourceError& WebError::resourceError() const
239 {
240 return m_error;
241 }
242