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 #include "config.h"
     26 #include "WebKitDLL.h"
     27 #include "DefaultDownloadDelegate.h"
     28 
     29 #include "MarshallingHelpers.h"
     30 #include "WebKit.h"
     31 #include "WebKitLogging.h"
     32 #include "WebMutableURLRequest.h"
     33 #include <WebCore/COMPtr.h>
     34 #include <wtf/text/CString.h>
     35 
     36 #include <shlobj.h>
     37 #include <wchar.h>
     38 
     39 #include <WebCore/BString.h>
     40 
     41 using namespace WebCore;
     42 
     43 
     44 // DefaultDownloadDelegate ----------------------------------------------------------------
     45 
     46 DefaultDownloadDelegate::DefaultDownloadDelegate()
     47     : m_refCount(0)
     48 {
     49     gClassCount++;
     50     gClassNameCount.add("DefaultDownloadDelegate");
     51 }
     52 
     53 DefaultDownloadDelegate::~DefaultDownloadDelegate()
     54 {
     55     gClassCount--;
     56     gClassNameCount.remove("DefaultDownloadDelegate");
     57     HashSet<IWebDownload*>::iterator i = m_downloads.begin();
     58     for (;i != m_downloads.end(); ++i)
     59         (*i)->Release();
     60 }
     61 
     62 DefaultDownloadDelegate* DefaultDownloadDelegate::sharedInstance()
     63 {
     64     static COMPtr<DefaultDownloadDelegate> shared;
     65     if (!shared)
     66         shared.adoptRef(DefaultDownloadDelegate::createInstance());
     67     return shared.get();
     68 }
     69 
     70 DefaultDownloadDelegate* DefaultDownloadDelegate::createInstance()
     71 {
     72     DefaultDownloadDelegate* instance = new DefaultDownloadDelegate();
     73     instance->AddRef();
     74     return instance;
     75 }
     76 
     77 // IUnknown -------------------------------------------------------------------
     78 
     79 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::QueryInterface(REFIID riid, void** ppvObject)
     80 {
     81     *ppvObject = 0;
     82     if (IsEqualGUID(riid, IID_IUnknown))
     83         *ppvObject = static_cast<IUnknown*>(this);
     84     else if (IsEqualGUID(riid, IID_IWebDownloadDelegate))
     85         *ppvObject = static_cast<IWebDownloadDelegate*>(this);
     86     else
     87         return E_NOINTERFACE;
     88 
     89     AddRef();
     90     return S_OK;
     91 }
     92 
     93 ULONG STDMETHODCALLTYPE DefaultDownloadDelegate::AddRef()
     94 {
     95     return ++m_refCount;
     96 }
     97 
     98 ULONG STDMETHODCALLTYPE DefaultDownloadDelegate::Release()
     99 {
    100     ULONG newRef = --m_refCount;
    101     if (!newRef)
    102         delete(this);
    103 
    104     return newRef;
    105 }
    106 
    107 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::decideDestinationWithSuggestedFilename(IWebDownload *download, BSTR filename)
    108 {
    109     LOG(Download, "DefaultDownloadDelegate %p - decideDestinationWithSuggestedFilename %s", download, String(filename, SysStringLen(filename)).ascii().data());
    110 
    111     WCHAR pathChars[MAX_PATH];
    112     if (FAILED(SHGetFolderPath(0, CSIDL_DESKTOPDIRECTORY  | CSIDL_FLAG_CREATE, 0, 0, pathChars))) {
    113         if (FAILED(download->setDestination(filename, true))) {
    114             LOG_ERROR("Failed to set destination on file");
    115             return E_FAIL;
    116         }
    117         return S_OK;
    118     }
    119 
    120     size_t fullLength = wcslen(pathChars) + SysStringLen(filename) + 2;
    121     BSTR full = SysAllocStringLen(0, (UINT)fullLength);
    122     if (!full)
    123         return E_OUTOFMEMORY;
    124 
    125     wcscpy_s(full, fullLength, pathChars);
    126     wcscat_s(full, fullLength, L"\\");
    127     wcscat_s(full, fullLength, filename);
    128     BString fullPath;
    129     fullPath.adoptBSTR(full);
    130 
    131 #ifndef NDEBUG
    132     String debug((BSTR)fullPath, SysStringLen(BSTR(fullPath)));
    133     LOG(Download, "Setting path to %s", debug.ascii().data());
    134 #endif
    135 
    136     if (FAILED(download->setDestination(fullPath, true))) {
    137         LOG_ERROR("Failed to set destination on file");
    138         return E_FAIL;
    139     }
    140     return S_OK;
    141 }
    142 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::didCancelAuthenticationChallenge(IWebDownload* download, IWebURLAuthenticationChallenge* challenge)
    143 {
    144     LOG(Download, "DefaultDownloadDelegate %p - didCancelAuthenticationChallenge %p", download, challenge);
    145     download = 0;
    146     challenge = 0;
    147     return S_OK;
    148 }
    149 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::didCreateDestination(IWebDownload* download, BSTR destination)
    150 {
    151     LOG(Download, "DefaultDownloadDelegate %p - didCreateDestination %s", download, String(destination, SysStringLen(destination)).ascii().data());
    152     download = 0;
    153     destination = 0;
    154     return S_OK;
    155 }
    156 
    157 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::didReceiveAuthenticationChallenge(IWebDownload* download, IWebURLAuthenticationChallenge* challenge)
    158 {
    159     LOG(Download, "DefaultDownloadDelegate %p - didReceiveAuthenticationChallenge %p", download, challenge);
    160     download = 0;
    161     challenge = 0;
    162     return S_OK;
    163 }
    164 
    165 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::didReceiveDataOfLength(IWebDownload* download, unsigned length)
    166 {
    167     LOG(Download, "DefaultDownloadDelegate %p - didReceiveDataOfLength %i", download, length);
    168     download = 0;
    169     length = 0;
    170     return S_OK;
    171 }
    172 
    173 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::didReceiveResponse(IWebDownload* download, IWebURLResponse* response)
    174 {
    175     LOG(Download, "DefaultDownloadDelegate %p - didReceiveResponse %p", download, response);
    176     download = 0;
    177     response = 0;
    178     return S_OK;
    179 }
    180 
    181 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::shouldDecodeSourceDataOfMIMEType(IWebDownload* download, BSTR encodingType, BOOL* shouldDecode)
    182 {
    183     LOG(Download, "DefaultDownloadDelegate %p - shouldDecodeSourceDataOfMIMEType %s", download, String(encodingType, SysStringLen(encodingType)).ascii().data());
    184     download = 0;
    185     encodingType = 0;
    186     *shouldDecode = false;
    187     return S_OK;
    188 }
    189 
    190 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::willResumeWithResponse(IWebDownload* download, IWebURLResponse* response, long long fromByte)
    191 {
    192     LOG(Download, "DefaultDownloadDelegate %p - willResumeWithResponse %p, %q", download, response, fromByte);
    193     download = 0;
    194     response = 0;
    195     fromByte = 0;
    196     return S_OK;
    197 }
    198 
    199 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::willSendRequest(IWebDownload* download, IWebMutableURLRequest* request,
    200                                                                  IWebURLResponse* redirectResponse, IWebMutableURLRequest** finalRequest)
    201 {
    202     LOG(Download, "DefaultDownloadDelegate %p - willSendRequest %p %p", download, request, redirectResponse);
    203     download = 0;
    204     redirectResponse = 0;
    205     *finalRequest = request;
    206     (*finalRequest)->AddRef();
    207     return S_OK;
    208 }
    209 
    210 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::didBegin(IWebDownload* download)
    211 {
    212     LOG(Download, "DefaultDownloadDelegate %p - didBegin", download);
    213     registerDownload(download);
    214     return S_OK;
    215 }
    216 
    217 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::didFinish(IWebDownload* download)
    218 {
    219     LOG(Download, "DefaultDownloadDelegate %p - didFinish", download);
    220     unregisterDownload(download);
    221     return S_OK;
    222 }
    223 
    224 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::didFailWithError(IWebDownload* download, IWebError* error)
    225 {
    226     LOG(Download, "DefaultDownloadDelegate %p - didFailWithError %p", download, error);
    227     unregisterDownload(download);
    228     error = 0;
    229     return S_OK;
    230 }
    231 
    232 void DefaultDownloadDelegate::registerDownload(IWebDownload* download)
    233 {
    234     if (m_downloads.contains(download))
    235         return;
    236     download->AddRef();
    237     m_downloads.add(download);
    238 }
    239 
    240 void DefaultDownloadDelegate::unregisterDownload(IWebDownload* download)
    241 {
    242     if (m_downloads.contains(download)) {
    243         download->Release();
    244         m_downloads.remove(download);
    245     }
    246 }
    247