Home | History | Annotate | Download | only in win
      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