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 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 52 WebError::~WebError() 53 { 54 gClassCount--; 55 gClassNameCount.remove("WebError"); 56 } 57 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 65 WebError* WebError::createInstance() 66 { 67 return createInstance(ResourceError()); 68 } 69 70 // IUnknown ------------------------------------------------------------------- 71 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 90 ULONG STDMETHODCALLTYPE WebError::AddRef(void) 91 { 92 return ++m_refCount; 93 } 94 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 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 115 HRESULT STDMETHODCALLTYPE WebError::code( 116 /* [retval][out] */ int* result) 117 { 118 *result = m_error.errorCode(); 119 return S_OK; 120 } 121 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 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 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 151 HRESULT STDMETHODCALLTYPE WebError::localizedFailureReason( 152 /* [retval][out] */ BSTR* /*result*/) 153 { 154 ASSERT_NOT_REACHED(); 155 return E_NOTIMPL; 156 } 157 158 HRESULT STDMETHODCALLTYPE WebError::localizedRecoveryOptions( 159 /* [retval][out] */ IEnumVARIANT** /*result*/) 160 { 161 ASSERT_NOT_REACHED(); 162 return E_NOTIMPL; 163 } 164 165 HRESULT STDMETHODCALLTYPE WebError::localizedRecoverySuggestion( 166 /* [retval][out] */ BSTR* /*result*/) 167 { 168 ASSERT_NOT_REACHED(); 169 return E_NOTIMPL; 170 } 171 172 HRESULT STDMETHODCALLTYPE WebError::recoverAttempter( 173 /* [retval][out] */ IUnknown** /*result*/) 174 { 175 ASSERT_NOT_REACHED(); 176 return E_NOTIMPL; 177 } 178 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 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 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 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 238 const ResourceError& WebError::resourceError() const 239 { 240 return m_error; 241 } 242