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 37 using namespace WebCore; 38 39 // WebError --------------------------------------------------------------------- 40 41 WebError::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 50 WebError::~WebError() 51 { 52 gClassCount--; 53 gClassNameCount.remove("WebError"); 54 } 55 56 WebError* WebError::createInstance(const ResourceError& error, IPropertyBag* userInfo) 57 { 58 WebError* instance = new WebError(error, userInfo); 59 instance->AddRef(); 60 return instance; 61 } 62 63 WebError* WebError::createInstance() 64 { 65 return createInstance(ResourceError()); 66 } 67 68 // IUnknown ------------------------------------------------------------------- 69 70 HRESULT 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 88 ULONG STDMETHODCALLTYPE WebError::AddRef(void) 89 { 90 return ++m_refCount; 91 } 92 93 ULONG 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 104 HRESULT 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 113 HRESULT STDMETHODCALLTYPE WebError::code( 114 /* [retval][out] */ int* result) 115 { 116 *result = m_error.errorCode(); 117 return S_OK; 118 } 119 120 HRESULT 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 130 HRESULT 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 149 HRESULT STDMETHODCALLTYPE WebError::localizedFailureReason( 150 /* [retval][out] */ BSTR* /*result*/) 151 { 152 ASSERT_NOT_REACHED(); 153 return E_NOTIMPL; 154 } 155 156 HRESULT STDMETHODCALLTYPE WebError::localizedRecoveryOptions( 157 /* [retval][out] */ IEnumVARIANT** /*result*/) 158 { 159 ASSERT_NOT_REACHED(); 160 return E_NOTIMPL; 161 } 162 163 HRESULT STDMETHODCALLTYPE WebError::localizedRecoverySuggestion( 164 /* [retval][out] */ BSTR* /*result*/) 165 { 166 ASSERT_NOT_REACHED(); 167 return E_NOTIMPL; 168 } 169 170 HRESULT STDMETHODCALLTYPE WebError::recoverAttempter( 171 /* [retval][out] */ IUnknown** /*result*/) 172 { 173 ASSERT_NOT_REACHED(); 174 return E_NOTIMPL; 175 } 176 177 HRESULT 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 190 HRESULT 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 200 HRESULT 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 211 HRESULT 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 236 const ResourceError& WebError::resourceError() const 237 { 238 return m_error; 239 } 240