kernel32: Update version to Win 10.
[wine.git] / dlls / urlmon / ftp.c
blob8e6ec4eaf89b49fa43babe1e2cb6552295090ab6
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 IUnknown IUnknown_inner;
32 IInternetProtocolEx IInternetProtocolEx_iface;
33 IInternetPriority IInternetPriority_iface;
34 IWinInetHttpInfo IWinInetHttpInfo_iface;
36 LONG ref;
37 IUnknown *outer;
38 } FtpProtocol;
40 static inline FtpProtocol *impl_from_IUnknown(IUnknown *iface)
42 return CONTAINING_RECORD(iface, FtpProtocol, IUnknown_inner);
45 static inline FtpProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface)
47 return CONTAINING_RECORD(iface, FtpProtocol, IInternetProtocolEx_iface);
50 static inline FtpProtocol *impl_from_IInternetPriority(IInternetPriority *iface)
52 return CONTAINING_RECORD(iface, FtpProtocol, IInternetPriority_iface);
54 static inline FtpProtocol *impl_from_IWinInetHttpInfo(IWinInetHttpInfo *iface)
57 return CONTAINING_RECORD(iface, FtpProtocol, IWinInetHttpInfo_iface);
60 static inline FtpProtocol *impl_from_Protocol(Protocol *prot)
62 return CONTAINING_RECORD(prot, FtpProtocol, base);
65 static HRESULT FtpProtocol_open_request(Protocol *prot, IUri *uri, DWORD request_flags,
66 HINTERNET internet_session, IInternetBindInfo *bind_info)
68 FtpProtocol *This = impl_from_Protocol(prot);
69 DWORD path_size = 0;
70 BSTR url;
71 HRESULT hres;
73 hres = IUri_GetAbsoluteUri(uri, &url);
74 if(FAILED(hres))
75 return hres;
77 hres = UrlUnescapeW(url, NULL, &path_size, URL_UNESCAPE_INPLACE);
78 if(SUCCEEDED(hres)) {
79 This->base.request = InternetOpenUrlW(internet_session, url, NULL, 0,
80 request_flags|INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_PASSIVE,
81 (DWORD_PTR)&This->base);
82 if (!This->base.request && GetLastError() != ERROR_IO_PENDING) {
83 WARN("InternetOpenUrl failed: %d\n", GetLastError());
84 hres = INET_E_RESOURCE_NOT_FOUND;
87 SysFreeString(url);
88 return hres;
91 static HRESULT FtpProtocol_end_request(Protocol *prot)
93 return E_NOTIMPL;
96 static HRESULT FtpProtocol_start_downloading(Protocol *prot)
98 FtpProtocol *This = impl_from_Protocol(prot);
99 DWORD size;
100 BOOL res;
102 res = FtpGetFileSize(This->base.request, &size);
103 if(res)
104 This->base.content_length = size;
105 else
106 WARN("FtpGetFileSize failed: %d\n", GetLastError());
108 return S_OK;
111 static void FtpProtocol_close_connection(Protocol *prot)
115 static void FtpProtocol_on_error(Protocol *prot, DWORD error)
117 FIXME("(%p) %d - stub\n", prot, error);
120 static const ProtocolVtbl AsyncProtocolVtbl = {
121 FtpProtocol_open_request,
122 FtpProtocol_end_request,
123 FtpProtocol_start_downloading,
124 FtpProtocol_close_connection,
125 FtpProtocol_on_error
128 static HRESULT WINAPI FtpProtocolUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
130 FtpProtocol *This = impl_from_IUnknown(iface);
132 if(IsEqualGUID(&IID_IUnknown, riid)) {
133 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
134 *ppv = &This->IUnknown_inner;
135 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
136 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
137 *ppv = &This->IInternetProtocolEx_iface;
138 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
139 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
140 *ppv = &This->IInternetProtocolEx_iface;
141 }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
142 TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv);
143 *ppv = &This->IInternetProtocolEx_iface;
144 }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
145 TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
146 *ppv = &This->IInternetPriority_iface;
147 }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
148 TRACE("(%p)->(IID_IWinInetInfo %p)\n", This, ppv);
149 *ppv = &This->IWinInetHttpInfo_iface;
150 }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
151 TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv);
152 *ppv = &This->IWinInetHttpInfo_iface;
153 }else {
154 *ppv = NULL;
155 WARN("not supported interface %s\n", debugstr_guid(riid));
156 return E_NOINTERFACE;
159 IUnknown_AddRef((IUnknown*)*ppv);
160 return S_OK;
163 static ULONG WINAPI FtpProtocolUnk_AddRef(IUnknown *iface)
165 FtpProtocol *This = impl_from_IUnknown(iface);
166 LONG ref = InterlockedIncrement(&This->ref);
167 TRACE("(%p) ref=%d\n", This, ref);
168 return ref;
171 static ULONG WINAPI FtpProtocolUnk_Release(IUnknown *iface)
173 FtpProtocol *This = impl_from_IUnknown(iface);
174 LONG ref = InterlockedDecrement(&This->ref);
176 TRACE("(%p) ref=%d\n", This, ref);
178 if(!ref) {
179 protocol_close_connection(&This->base);
180 heap_free(This);
182 URLMON_UnlockModule();
185 return ref;
188 static const IUnknownVtbl FtpProtocolUnkVtbl = {
189 FtpProtocolUnk_QueryInterface,
190 FtpProtocolUnk_AddRef,
191 FtpProtocolUnk_Release
194 static HRESULT WINAPI FtpProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
196 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
197 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
198 return IUnknown_QueryInterface(This->outer, riid, ppv);
201 static ULONG WINAPI FtpProtocol_AddRef(IInternetProtocolEx *iface)
203 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
204 TRACE("(%p)\n", This);
205 return IUnknown_AddRef(This->outer);
208 static ULONG WINAPI FtpProtocol_Release(IInternetProtocolEx *iface)
210 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
211 TRACE("(%p)\n", This);
212 return IUnknown_Release(This->outer);
215 static HRESULT WINAPI FtpProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
216 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
217 DWORD grfPI, HANDLE_PTR dwReserved)
219 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
220 IUri *uri;
221 HRESULT hres;
223 TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
224 pOIBindInfo, grfPI, dwReserved);
226 hres = CreateUri(szUrl, 0, 0, &uri);
227 if(FAILED(hres))
228 return hres;
230 hres = IInternetProtocolEx_StartEx(&This->IInternetProtocolEx_iface, uri, pOIProtSink,
231 pOIBindInfo, grfPI, (HANDLE*)dwReserved);
233 IUri_Release(uri);
234 return hres;
237 static HRESULT WINAPI FtpProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
239 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
241 TRACE("(%p)->(%p)\n", This, pProtocolData);
243 return protocol_continue(&This->base, pProtocolData);
246 static HRESULT WINAPI FtpProtocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
247 DWORD dwOptions)
249 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
251 TRACE("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
253 return protocol_abort(&This->base, hrReason);
256 static HRESULT WINAPI FtpProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
258 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
260 TRACE("(%p)->(%08x)\n", This, dwOptions);
262 protocol_close_connection(&This->base);
263 return S_OK;
266 static HRESULT WINAPI FtpProtocol_Suspend(IInternetProtocolEx *iface)
268 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
269 FIXME("(%p)\n", This);
270 return E_NOTIMPL;
273 static HRESULT WINAPI FtpProtocol_Resume(IInternetProtocolEx *iface)
275 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
276 FIXME("(%p)\n", This);
277 return E_NOTIMPL;
280 static HRESULT WINAPI FtpProtocol_Read(IInternetProtocolEx *iface, void *pv,
281 ULONG cb, ULONG *pcbRead)
283 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
285 TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
287 return protocol_read(&This->base, pv, cb, pcbRead);
290 static HRESULT WINAPI FtpProtocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove,
291 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
293 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
294 FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
295 return E_NOTIMPL;
298 static HRESULT WINAPI FtpProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
300 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
302 TRACE("(%p)->(%08x)\n", This, dwOptions);
304 return protocol_lock_request(&This->base);
307 static HRESULT WINAPI FtpProtocol_UnlockRequest(IInternetProtocolEx *iface)
309 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
311 TRACE("(%p)\n", This);
313 return protocol_unlock_request(&This->base);
316 static HRESULT WINAPI FtpProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri,
317 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
318 DWORD grfPI, HANDLE *dwReserved)
320 FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
321 DWORD scheme = 0;
322 HRESULT hres;
324 TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink,
325 pOIBindInfo, grfPI, dwReserved);
327 hres = IUri_GetScheme(pUri, &scheme);
328 if(FAILED(hres))
329 return hres;
330 if(scheme != URL_SCHEME_FTP)
331 return MK_E_SYNTAX;
333 return protocol_start(&This->base, (IInternetProtocol*)&This->IInternetProtocolEx_iface, pUri,
334 pOIProtSink, pOIBindInfo);
337 static const IInternetProtocolExVtbl FtpProtocolVtbl = {
338 FtpProtocol_QueryInterface,
339 FtpProtocol_AddRef,
340 FtpProtocol_Release,
341 FtpProtocol_Start,
342 FtpProtocol_Continue,
343 FtpProtocol_Abort,
344 FtpProtocol_Terminate,
345 FtpProtocol_Suspend,
346 FtpProtocol_Resume,
347 FtpProtocol_Read,
348 FtpProtocol_Seek,
349 FtpProtocol_LockRequest,
350 FtpProtocol_UnlockRequest,
351 FtpProtocol_StartEx
354 static HRESULT WINAPI FtpPriority_QueryInterface(IInternetPriority *iface, REFIID riid, void **ppv)
356 FtpProtocol *This = impl_from_IInternetPriority(iface);
357 return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
360 static ULONG WINAPI FtpPriority_AddRef(IInternetPriority *iface)
362 FtpProtocol *This = impl_from_IInternetPriority(iface);
363 return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
366 static ULONG WINAPI FtpPriority_Release(IInternetPriority *iface)
368 FtpProtocol *This = impl_from_IInternetPriority(iface);
369 return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
372 static HRESULT WINAPI FtpPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
374 FtpProtocol *This = impl_from_IInternetPriority(iface);
376 TRACE("(%p)->(%d)\n", This, nPriority);
378 This->base.priority = nPriority;
379 return S_OK;
382 static HRESULT WINAPI FtpPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
384 FtpProtocol *This = impl_from_IInternetPriority(iface);
386 TRACE("(%p)->(%p)\n", This, pnPriority);
388 *pnPriority = This->base.priority;
389 return S_OK;
392 static const IInternetPriorityVtbl FtpPriorityVtbl = {
393 FtpPriority_QueryInterface,
394 FtpPriority_AddRef,
395 FtpPriority_Release,
396 FtpPriority_SetPriority,
397 FtpPriority_GetPriority
400 static HRESULT WINAPI HttpInfo_QueryInterface(IWinInetHttpInfo *iface, REFIID riid, void **ppv)
402 FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
403 return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv);
406 static ULONG WINAPI HttpInfo_AddRef(IWinInetHttpInfo *iface)
408 FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
409 return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface);
412 static ULONG WINAPI HttpInfo_Release(IWinInetHttpInfo *iface)
414 FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
415 return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface);
418 static HRESULT WINAPI HttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD dwOption,
419 void *pBuffer, DWORD *pcbBuffer)
421 FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
422 TRACE("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer);
424 if(!This->base.request)
425 return E_FAIL;
427 if(!InternetQueryOptionW(This->base.request, dwOption, pBuffer, pcbBuffer))
428 return S_FALSE;
429 return S_OK;
432 static HRESULT WINAPI HttpInfo_QueryInfo(IWinInetHttpInfo *iface, DWORD dwOption,
433 void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved)
435 FtpProtocol *This = impl_from_IWinInetHttpInfo(iface);
436 TRACE("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
438 if(!This->base.request)
439 return E_FAIL;
441 if(!HttpQueryInfoW(This->base.request, dwOption, pBuffer, pcbBuffer, pdwFlags))
442 return S_FALSE;
443 return S_OK;
446 static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = {
447 HttpInfo_QueryInterface,
448 HttpInfo_AddRef,
449 HttpInfo_Release,
450 HttpInfo_QueryOption,
451 HttpInfo_QueryInfo
454 HRESULT FtpProtocol_Construct(IUnknown *outer, void **ppv)
456 FtpProtocol *ret;
458 TRACE("(%p %p)\n", outer, ppv);
460 URLMON_LockModule();
462 ret = heap_alloc_zero(sizeof(FtpProtocol));
464 ret->base.vtbl = &AsyncProtocolVtbl;
465 ret->IUnknown_inner.lpVtbl = &FtpProtocolUnkVtbl;
466 ret->IInternetProtocolEx_iface.lpVtbl = &FtpProtocolVtbl;
467 ret->IInternetPriority_iface.lpVtbl = &FtpPriorityVtbl;
468 ret->IWinInetHttpInfo_iface.lpVtbl = &WinInetHttpInfoVtbl;
469 ret->ref = 1;
470 ret->outer = outer ? outer : &ret->IUnknown_inner;
472 *ppv = &ret->IUnknown_inner;
473 return S_OK;