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