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 39using namespace WebCore; 40 41// WebError --------------------------------------------------------------------- 42 43WebError::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 52WebError::~WebError() 53{ 54 gClassCount--; 55 gClassNameCount.remove("WebError"); 56} 57 58WebError* WebError::createInstance(const ResourceError& error, IPropertyBag* userInfo) 59{ 60 WebError* instance = new WebError(error, userInfo); 61 instance->AddRef(); 62 return instance; 63} 64 65WebError* WebError::createInstance() 66{ 67 return createInstance(ResourceError()); 68} 69 70// IUnknown ------------------------------------------------------------------- 71 72HRESULT 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 90ULONG STDMETHODCALLTYPE WebError::AddRef(void) 91{ 92 return ++m_refCount; 93} 94 95ULONG 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 106HRESULT 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 115HRESULT STDMETHODCALLTYPE WebError::code( 116 /* [retval][out] */ int* result) 117{ 118 *result = m_error.errorCode(); 119 return S_OK; 120} 121 122HRESULT 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 132HRESULT 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 USE(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 151HRESULT STDMETHODCALLTYPE WebError::localizedFailureReason( 152 /* [retval][out] */ BSTR* /*result*/) 153{ 154 ASSERT_NOT_REACHED(); 155 return E_NOTIMPL; 156} 157 158HRESULT STDMETHODCALLTYPE WebError::localizedRecoveryOptions( 159 /* [retval][out] */ IEnumVARIANT** /*result*/) 160{ 161 ASSERT_NOT_REACHED(); 162 return E_NOTIMPL; 163} 164 165HRESULT STDMETHODCALLTYPE WebError::localizedRecoverySuggestion( 166 /* [retval][out] */ BSTR* /*result*/) 167{ 168 ASSERT_NOT_REACHED(); 169 return E_NOTIMPL; 170} 171 172HRESULT STDMETHODCALLTYPE WebError::recoverAttempter( 173 /* [retval][out] */ IUnknown** /*result*/) 174{ 175 ASSERT_NOT_REACHED(); 176 return E_NOTIMPL; 177} 178 179HRESULT 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 192HRESULT 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 202HRESULT 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 213HRESULT 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 238const ResourceError& WebError::resourceError() const 239{ 240 return m_error; 241} 242