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
34 #include <shlobj.h>
35 #include <tchar.h>
36
37 #pragma warning(push, 0)
38 #include <WebCore/BString.h>
39 #pragma warning(pop)
40
41 using namespace WebCore;
42
43
44 // DefaultDownloadDelegate ----------------------------------------------------------------
45
DefaultDownloadDelegate()46 DefaultDownloadDelegate::DefaultDownloadDelegate()
47 : m_refCount(0)
48 {
49 gClassCount++;
50 gClassNameCount.add("DefaultDownloadDelegate");
51 }
52
~DefaultDownloadDelegate()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
sharedInstance()62 DefaultDownloadDelegate* DefaultDownloadDelegate::sharedInstance()
63 {
64 static COMPtr<DefaultDownloadDelegate> shared;
65 if (!shared)
66 shared.adoptRef(DefaultDownloadDelegate::createInstance());
67 return shared.get();
68 }
69
createInstance()70 DefaultDownloadDelegate* DefaultDownloadDelegate::createInstance()
71 {
72 DefaultDownloadDelegate* instance = new DefaultDownloadDelegate();
73 instance->AddRef();
74 return instance;
75 }
76
77 // IUnknown -------------------------------------------------------------------
78
QueryInterface(REFIID riid,void ** ppvObject)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
AddRef()93 ULONG STDMETHODCALLTYPE DefaultDownloadDelegate::AddRef()
94 {
95 return ++m_refCount;
96 }
97
Release()98 ULONG STDMETHODCALLTYPE DefaultDownloadDelegate::Release()
99 {
100 ULONG newRef = --m_refCount;
101 if (!newRef)
102 delete(this);
103
104 return newRef;
105 }
106
decideDestinationWithSuggestedFilename(IWebDownload * download,BSTR filename)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 TCHAR 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 = _tcslen(pathChars) + SysStringLen(filename) + 2;
121 BSTR full = SysAllocStringLen(0, (UINT)fullLength);
122 if (!full)
123 return E_OUTOFMEMORY;
124
125 _tcscpy_s(full, fullLength, pathChars);
126 _tcscat_s(full, fullLength, _T("\\"));
127 _tcscat_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 }
didCancelAuthenticationChallenge(IWebDownload * download,IWebURLAuthenticationChallenge * challenge)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 }
didCreateDestination(IWebDownload * download,BSTR destination)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
didReceiveAuthenticationChallenge(IWebDownload * download,IWebURLAuthenticationChallenge * challenge)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
didReceiveDataOfLength(IWebDownload * download,unsigned length)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
didReceiveResponse(IWebDownload * download,IWebURLResponse * response)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
shouldDecodeSourceDataOfMIMEType(IWebDownload * download,BSTR encodingType,BOOL * shouldDecode)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
willResumeWithResponse(IWebDownload * download,IWebURLResponse * response,long long fromByte)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
willSendRequest(IWebDownload * download,IWebMutableURLRequest * request,IWebURLResponse * redirectResponse,IWebMutableURLRequest ** finalRequest)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 return S_OK;
207 }
208
didBegin(IWebDownload * download)209 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::didBegin(IWebDownload* download)
210 {
211 LOG(Download, "DefaultDownloadDelegate %p - didBegin", download);
212 registerDownload(download);
213 return S_OK;
214 }
215
didFinish(IWebDownload * download)216 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::didFinish(IWebDownload* download)
217 {
218 LOG(Download, "DefaultDownloadDelegate %p - didFinish", download);
219 unregisterDownload(download);
220 return S_OK;
221 }
222
didFailWithError(IWebDownload * download,IWebError * error)223 HRESULT STDMETHODCALLTYPE DefaultDownloadDelegate::didFailWithError(IWebDownload* download, IWebError* error)
224 {
225 LOG(Download, "DefaultDownloadDelegate %p - didFailWithError %p", download, error);
226 unregisterDownload(download);
227 error = 0;
228 return S_OK;
229 }
230
registerDownload(IWebDownload * download)231 void DefaultDownloadDelegate::registerDownload(IWebDownload* download)
232 {
233 if (m_downloads.contains(download))
234 return;
235 download->AddRef();
236 m_downloads.add(download);
237 }
238
unregisterDownload(IWebDownload * download)239 void DefaultDownloadDelegate::unregisterDownload(IWebDownload* download)
240 {
241 if (m_downloads.contains(download)) {
242 download->Release();
243 m_downloads.remove(download);
244 }
245 }
246