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 "DefaultPolicyDelegate.h"
     29 
     30 #include "WebKit.h"
     31 
     32 #pragma warning(push, 0)
     33 #include <WebCore/PlatformString.h>
     34 #pragma warning(pop)
     35 
     36 using namespace WebCore;
     37 
     38 // FIXME: move this enum to a separate header file when other code begins to use it.
     39 typedef enum WebExtraNavigationType {
     40     WebNavigationTypePlugInRequest = WebNavigationTypeOther + 1
     41 } WebExtraNavigationType;
     42 
     43 // DefaultPolicyDelegate ----------------------------------------------------------------
     44 
     45 DefaultPolicyDelegate::DefaultPolicyDelegate()
     46     : m_refCount(0)
     47 {
     48     gClassCount++;
     49     gClassNameCount.add("DefaultPolicyDelegate");
     50 }
     51 
     52 DefaultPolicyDelegate::~DefaultPolicyDelegate()
     53 {
     54     gClassCount--;
     55     gClassNameCount.remove("DefaultPolicyDelegate");
     56 }
     57 
     58 DefaultPolicyDelegate* DefaultPolicyDelegate::sharedInstance()
     59 {
     60     static COMPtr<DefaultPolicyDelegate> shared;
     61     if (!shared)
     62         shared.adoptRef(DefaultPolicyDelegate::createInstance());
     63     return shared.get();
     64 }
     65 
     66 DefaultPolicyDelegate* DefaultPolicyDelegate::createInstance()
     67 {
     68     DefaultPolicyDelegate* instance = new DefaultPolicyDelegate();
     69     instance->AddRef();
     70     return instance;
     71 }
     72 
     73 // IUnknown -------------------------------------------------------------------
     74 
     75 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::QueryInterface(REFIID riid, void** ppvObject)
     76 {
     77     *ppvObject = 0;
     78     if (IsEqualGUID(riid, IID_IUnknown))
     79         *ppvObject = static_cast<IUnknown*>(this);
     80     else if (IsEqualGUID(riid, IID_IWebPolicyDelegate))
     81         *ppvObject = static_cast<IWebPolicyDelegate*>(this);
     82     else
     83         return E_NOINTERFACE;
     84 
     85     AddRef();
     86     return S_OK;
     87 }
     88 
     89 ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::AddRef()
     90 {
     91     return ++m_refCount;
     92 }
     93 
     94 ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::Release()
     95 {
     96     ULONG newRef = --m_refCount;
     97     if (!newRef)
     98         delete(this);
     99 
    100     return newRef;
    101 }
    102 
    103 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForNavigationAction(
    104     /*[in]*/ IWebView* webView,
    105     /*[in]*/ IPropertyBag* actionInformation,
    106     /*[in]*/ IWebURLRequest* request,
    107     /*[in]*/ IWebFrame* /*frame*/,
    108     /*[in]*/ IWebPolicyDecisionListener* listener)
    109 {
    110     int navType = 0;
    111     VARIANT var;
    112     if (SUCCEEDED(actionInformation->Read(WebActionNavigationTypeKey, &var, 0))) {
    113         V_VT(&var) = VT_I4;
    114         navType = V_I4(&var);
    115     }
    116     COMPtr<IWebViewPrivate> wvPrivate(Query, webView);
    117     if (wvPrivate) {
    118         BOOL canHandleRequest = FALSE;
    119         if (SUCCEEDED(wvPrivate->canHandleRequest(request, &canHandleRequest)) && canHandleRequest)
    120             listener->use();
    121         else if (navType == WebNavigationTypePlugInRequest)
    122             listener->use();
    123         else {
    124             BSTR url;
    125             // A file URL shouldn't fall through to here, but if it did,
    126             // it would be a security risk to open it.
    127             if (SUCCEEDED(request->URL(&url)) && !String(url, SysStringLen(url)).startsWith("file:")) {
    128                 // FIXME: Open the URL not by means of a webframe, but by handing it over to the system and letting it determine how to open that particular URL scheme.  See documentation for [NSWorkspace openURL]
    129                 ;
    130             }
    131             listener->ignore();
    132             SysFreeString(url);
    133         }
    134     }
    135     return S_OK;
    136 }
    137 
    138 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForNewWindowAction(
    139     /*[in]*/ IWebView* /*webView*/,
    140     /*[in]*/ IPropertyBag* /*actionInformation*/,
    141     /*[in]*/ IWebURLRequest* /*request*/,
    142     /*[in]*/ BSTR /*frameName*/,
    143     /*[in]*/ IWebPolicyDecisionListener* listener)
    144 {
    145     listener->use();
    146     return S_OK;
    147 }
    148 
    149 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForMIMEType(
    150     /*[in]*/ IWebView* webView,
    151     /*[in]*/ BSTR type,
    152     /*[in]*/ IWebURLRequest* request,
    153     /*[in]*/ IWebFrame* /*frame*/,
    154     /*[in]*/ IWebPolicyDecisionListener* listener)
    155 {
    156     BOOL canShowMIMEType;
    157     if (FAILED(webView->canShowMIMEType(type, &canShowMIMEType)))
    158         canShowMIMEType = FALSE;
    159 
    160     BSTR url;
    161     request->URL(&url);
    162 
    163     if (String(url, SysStringLen(url)).startsWith("file:")) {
    164         BOOL isDirectory = FALSE;
    165         WIN32_FILE_ATTRIBUTE_DATA attrs;
    166         if (GetFileAttributesEx(url, GetFileExInfoStandard, &attrs))
    167             isDirectory = !!(attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
    168 
    169         if (isDirectory)
    170             listener->ignore();
    171         else if(canShowMIMEType)
    172             listener->use();
    173         else
    174             listener->ignore();
    175     } else if (canShowMIMEType)
    176         listener->use();
    177     else
    178         listener->ignore();
    179     SysFreeString(url);
    180     return S_OK;
    181 }
    182 
    183 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::unableToImplementPolicyWithError(
    184     /*[in]*/ IWebView* /*webView*/,
    185     /*[in]*/ IWebError* error,
    186     /*[in]*/ IWebFrame* frame)
    187 {
    188     BSTR errorStr;
    189     error->localizedDescription(&errorStr);
    190 
    191     BSTR frameName;
    192     frame->name(&frameName);
    193 
    194     LOG_ERROR("called unableToImplementPolicyWithError:%S inFrame:%S", errorStr ? errorStr : TEXT(""), frameName ? frameName : TEXT(""));
    195     SysFreeString(errorStr);
    196     SysFreeString(frameName);
    197 
    198     return S_OK;
    199 }
    200