msvcp60: Manually define virtual destructors in vtables.
[wine/multimedia.git] / dlls / urlmon / ftp.c
blobda1efe202deaa8afb3bf764ba28671baba4fa1eb
1 /*
2 * Copyright 2005-2009 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "urlmon_main.h"
21 #define NO_SHLWAPI_REG
22 #include "shlwapi.h"
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
28 typedef struct {
29 Protocol base;
31 IInternetProtocolEx IInternetProtocolEx_iface;
32 IInternetPriority IInternetPriority_iface;
33 IWinInetHttpInfo IWinInetHttpInfo_iface;
35 LONG ref;
36 } FtpProtocol;
38 static inline FtpProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface)
40 return CONTAINING_RECORD(iface, FtpProtocol, IInternetProtocolEx_iface);
43 static inline FtpProtocol *impl_from_IInternetPriority(IInternetPriority *iface)
45 return CONTAINING_RECORD(iface, FtpProtocol, IInternetPriority_iface);
47 static inline FtpProtocol *impl_from_IWinInetHttpInfo(IWinInetHttpInfo *iface)
50 return CONTAINING_RECORD(iface, FtpProtocol, IWinInetHttpInfo_iface);
53 static inline FtpProtocol *impl_from_Protocol(Protocol *prot)
55 return CONTAINING_RECORD(prot, FtpProtocol, base);
58 static HRESULT FtpProtocol_open_request(Protocol *prot, IUri *uri, DWORD request_flags,
59 HINTERNET internet_session, IInternetBindInfo *bind_info)
61 FtpProtocol *This = impl_from_Protocol(prot);
62 BSTR url;
63 HRESULT hres;
65 hres = IUri_GetAbsoluteUri(uri, &url);
66 if(FAILED(hres))
67 return hres;
69 This->base.request = InternetOpenUrlW(internet_session, url, NULL, 0,
70 request_flags|INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_PASSIVE,
71 (DWORD_PTR)&This->base);
72 SysFreeString(url);
73 if (!This->base.request && GetLastError() != ERROR_IO_PENDING) {
74 WARN("InternetOpenUrl failed: %d\n", GetLastError());
75 return INET_E_RESOURCE_NOT_FOUND;
78 return S_OK;
81 static HRESULT FtpProtocol_end_request(Protocol *prot)
83 return E_NOTIMPL;
86 static HRESULT FtpProtocol_start_downloading(Protocol *prot)
88 FtpProtocol *This = impl_from_Protocol(prot);
89 DWORD size;
90 BOOL res;
92 res = FtpGetFileSize(This->base.request, &size);
93 if(res)
94 This->base.content_length = size;
95 else
96 WARN("FtpGetFileSize failed: %d\n", GetLastError());
98 return S_OK;
101 static void FtpProtocol_close_connection(Protocol *prot)
105 static void FtpProtocol_on_error(Protocol *prot, DWORD error)
107 FIXME("(%p) %d - stub\n", prot, error);
110 static const ProtocolVtbl AsyncProtocolVtbl = {
111 FtpProtocol_open_request,
112 FtpProtocol_end_request,
113 FtpProtocol_start_downloading,
114 FtpProtocol_close_connection,
115 FtpProtocol_on_error
118 static HRESULT WINAPI FtpProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
120 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
122 *ppv = NULL;
123 if(IsEqualGUID(&IID_IUnknown, riid)) {
124 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
125 *ppv = &This->IInternetProtocolEx_iface;
126 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
127 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
128 *ppv = &This->IInternetProtocolEx_iface;
129 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
130 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
131 *ppv = &This->IInternetProtocolEx_iface;
132 }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
133 TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv);
134 *ppv = &This->IInternetProtocolEx_iface;
135 }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
136 TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
137 *ppv = &This->IInternetPriority_iface;
138 }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
139 TRACE("(%p)->(IID_IWinInetInfo %p)\n", This, ppv);
140 *ppv = &This->IWinInetHttpInfo_iface;
141 }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
142 TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv);
143 *ppv = &This->IWinInetHttpInfo_iface;
146 if(*ppv) {
147 IInternetProtocolEx_AddRef(iface);
148 return S_OK;
151 WARN("not supported interface %s\n", debugstr_guid(riid));
152 return E_NOINTERFACE;
155 static ULONG WINAPI FtpProtocol_AddRef(IInternetProtocolEx *iface)
157 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
158 LONG ref = InterlockedIncrement(&This->ref);
159 TRACE("(%p) ref=%d\n", This, ref);
160 return ref;
163 static ULONG WINAPI FtpProtocol_Release(IInternetProtocolEx *iface)
165 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
166 LONG ref = InterlockedDecrement(&This->ref);
168 TRACE("(%p) ref=%d\n", This, ref);
170 if(!ref) {
171 protocol_close_connection(&This->base);
172 heap_free(This);
174 URLMON_UnlockModule();
177 return ref;
180 static HRESULT WINAPI FtpProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
181 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
182 DWORD grfPI, HANDLE_PTR dwReserved)
184 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
185 IUri *uri;
186 HRESULT hres;
188 TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
189 pOIBindInfo, grfPI, dwReserved);
191 hres = CreateUri(szUrl, 0, 0, &uri);
192 if(FAILED(hres))
193 return hres;
195 hres = IInternetProtocolEx_StartEx(&This->IInternetProtocolEx_iface, uri, pOIProtSink,
196 pOIBindInfo, grfPI, (HANDLE*)dwReserved);
198 IUri_Release(uri);
199 return hres;
202 static HRESULT WINAPI FtpProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
204 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
206 TRACE("(%p)->(%p)\n", This, pProtocolData);
208 return protocol_continue(&This->base, pProtocolData);
211 static HRESULT WINAPI FtpProtocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
212 DWORD dwOptions)
214 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
216 TRACE("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
218 return protocol_abort(&This->base, hrReason);
221 static HRESULT WINAPI FtpProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
223 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
225 TRACE("(%p)->(%08x)\n", This, dwOptions);
227 protocol_close_connection(&This->base);
228 return S_OK;
231 static HRESULT WINAPI FtpProtocol_Suspend(IInternetProtocolEx *iface)
233 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
234 FIXME("(%p)\n", This);
235 return E_NOTIMPL;
238 static HRESULT WINAPI FtpProtocol_Resume(IInternetProtocolEx *iface)
240 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
241 FIXME("(%p)\n", This);
242 return E_NOTIMPL;
245 static HRESULT WINAPI FtpProtocol_Read(IInternetProtocolEx *iface, void *pv,
246 ULONG cb, ULONG *pcbRead)
248 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
250 TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
252 return protocol_read(&This->base, pv, cb, pcbRead);
255 static HRESULT WINAPI FtpProtocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove,
256 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
258 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
259 FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
260 return E_NOTIMPL;
263 static HRESULT WINAPI FtpProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
265 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
267 TRACE("(%p)->(%08x)\n", This, dwOptions);
269 return protocol_lock_request(&This->base);
272 static HRESULT WINAPI FtpProtocol_UnlockRequest(IInternetProtocolEx *iface)
274 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
276 TRACE("(%p)\n", This);
278 return protocol_unlock_request(&This->base);
281 static HRESULT WINAPI FtpProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri,
282 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
283 DWORD grfPI, HANDLE *dwReserved)
285 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
286 DWORD scheme = 0;
287 HRESULT hres;
289 TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink,
290 pOIBindInfo, grfPI, dwReserved);
292 hres = IUri_GetScheme(pUri, &scheme);
293 if(FAILED(hres))
294 return hres;
295 if(scheme != URL_SCHEME_FTP)
296 return MK_E_SYNTAX;
298 return protocol_start(&This->base, (IInternetProtocol*)&This->IInternetProtocolEx_iface, pUri,
299 pOIProtSink, pOIBindInfo);
302 static const IInternetProtocolExVtbl FtpProtocolVtbl = {
303 FtpProtocol_QueryInterface,
304 FtpProtocol_AddRef,
305 FtpProtocol_Release,
306 FtpProtocol_Start,
307 FtpProtocol_Continue,
308 FtpProtocol_Abort,
309 FtpProtocol_Terminate,
310 FtpProtocol_Suspend,
311 FtpProtocol_Resume,
312 FtpProtocol_Read,
313 FtpProtocol_Seek,
314 FtpProtocol_LockRequest,
315 FtpProtocol_UnlockRequest,
316 FtpProtocol_StartEx
319 static HRESULT WINAPI FtpPriority_QueryInterface(IInternetPriority *iface, REFIID riid, void **ppv)
321 FtpProtocol *This = impl_from_IInternetPriority(iface);
322 return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
325 static ULONG WINAPI FtpPriority_AddRef(IInternetPriority *iface)
327 FtpProtocol *This = impl_from_IInternetPriority(iface);
328 return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
331 static ULONG WINAPI FtpPriority_Release(IInternetPriority *iface)
333 FtpProtocol *This = impl_from_IInternetPriority(iface);
334 return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
337 static HRESULT WINAPI FtpPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
339 FtpProtocol *This = impl_from_IInternetPriority(iface);
341 TRACE("(%p)->(%d)\n", This, nPriority);
343 This->base.priority = nPriority;
344 return S_OK;
347 static HRESULT WINAPI FtpPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
349 FtpProtocol *This = impl_from_IInternetPriority(iface);
351 TRACE("(%p)->(%p)\n", This, pnPriority);
353 *pnPriority = This->base.priority;
354 return S_OK;
357 static const IInternetPriorityVtbl FtpPriorityVtbl = {
358 FtpPriority_QueryInterface,
359 FtpPriority_AddRef,
360 FtpPriority_Release,
361 FtpPriority_SetPriority,
362 FtpPriority_GetPriority
365 static HRESULT WINAPI HttpInfo_QueryInterface(IWinInetHttpInfo *iface, REFIID riid, void **ppv)
367 FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
368 return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
371 static ULONG WINAPI HttpInfo_AddRef(IWinInetHttpInfo *iface)
373 FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
374 return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
377 static ULONG WINAPI HttpInfo_Release(IWinInetHttpInfo *iface)
379 FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
380 return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
383 static HRESULT WINAPI HttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD dwOption,
384 void *pBuffer, DWORD *pcbBuffer)
386 FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
387 TRACE("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer);
389 if(!This->base.request)
390 return E_FAIL;
392 if(!InternetQueryOptionW(This->base.request, dwOption, pBuffer, pcbBuffer))
393 return S_FALSE;
394 return S_OK;
397 static HRESULT WINAPI HttpInfo_QueryInfo(IWinInetHttpInfo *iface, DWORD dwOption,
398 void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved)
400 FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
401 TRACE("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
403 if(!This->base.request)
404 return E_FAIL;
406 if(!HttpQueryInfoW(This->base.request, dwOption, pBuffer, pcbBuffer, pdwFlags))
407 return S_FALSE;
408 return S_OK;
411 static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = {
412 HttpInfo_QueryInterface,
413 HttpInfo_AddRef,
414 HttpInfo_Release,
415 HttpInfo_QueryOption,
416 HttpInfo_QueryInfo
419 HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
421 FtpProtocol *ret;
423 TRACE("(%p %p)\n", pUnkOuter, ppobj);
425 URLMON_LockModule();
427 ret = heap_alloc_zero(sizeof(FtpProtocol));
429 ret->base.vtbl = &AsyncProtocolVtbl;
430 ret->IInternetProtocolEx_iface.lpVtbl = &FtpProtocolVtbl;
431 ret->IInternetPriority_iface.lpVtbl = &FtpPriorityVtbl;
432 ret->IWinInetHttpInfo_iface.lpVtbl = &WinInetHttpInfoVtbl;
433 ret->ref = 1;
435 *ppobj = &ret->IInternetProtocolEx_iface;
437 return S_OK;