push bc3e5bf5ba806943a97979264a1f2e4a4dde5c94
[wine/hacks.git] / dlls / urlmon / bindprot.c
blob6b175f630c624594b727605abf725cecf900d2a4
1 /*
2 * Copyright 2007 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 <stdarg.h>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27 #include "urlmon.h"
28 #include "urlmon_main.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
34 typedef struct {
35 const IInternetProtocolVtbl *lpInternetProtocolVtbl;
36 const IInternetBindInfoVtbl *lpInternetBindInfoVtbl;
37 const IInternetPriorityVtbl *lpInternetPriorityVtbl;
38 const IInternetProtocolSinkVtbl *lpInternetProtocolSinkVtbl;
40 LONG ref;
42 IInternetProtocol *protocol;
43 IInternetBindInfo *bind_info;
44 IInternetProtocolSink *protocol_sink;
46 LONG priority;
47 } BindProtocol;
49 #define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
50 #define BINDINFO(x) ((IInternetBindInfo*) &(x)->lpInternetBindInfoVtbl)
51 #define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
52 #define PROTSINK(x) ((IInternetProtocolSink*) &(x)->lpInternetProtocolSinkVtbl)
54 #define PROTOCOL_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocol, iface)
56 static HRESULT WINAPI BindProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
58 BindProtocol *This = PROTOCOL_THIS(iface);
60 *ppv = NULL;
61 if(IsEqualGUID(&IID_IUnknown, riid)) {
62 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
63 *ppv = PROTOCOL(This);
64 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
65 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
66 *ppv = PROTOCOL(This);
67 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
68 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
69 *ppv = PROTOCOL(This);
70 }else if(IsEqualGUID(&IID_IInternetBindInfo, riid)) {
71 TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This, ppv);
72 *ppv = BINDINFO(This);
73 }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
74 TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
75 *ppv = PRIORITY(This);
76 }else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
77 FIXME("(%p)->(IID_IAuthenticate %p)\n", This, ppv);
78 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
79 FIXME("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
80 }else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
81 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
82 *ppv = PROTSINK(This);
85 if(*ppv) {
86 IInternetProtocol_AddRef(iface);
87 return S_OK;
90 WARN("not supported interface %s\n", debugstr_guid(riid));
91 return E_NOINTERFACE;
94 static ULONG WINAPI BindProtocol_AddRef(IInternetProtocol *iface)
96 BindProtocol *This = PROTOCOL_THIS(iface);
97 LONG ref = InterlockedIncrement(&This->ref);
98 TRACE("(%p) ref=%d\n", This, ref);
99 return ref;
102 static ULONG WINAPI BindProtocol_Release(IInternetProtocol *iface)
104 BindProtocol *This = PROTOCOL_THIS(iface);
105 LONG ref = InterlockedDecrement(&This->ref);
107 TRACE("(%p) ref=%d\n", This, ref);
109 if(!ref) {
110 if(This->protocol)
111 IInternetProtocol_Release(This->protocol);
112 if(This->bind_info)
113 IInternetBindInfo_Release(This->bind_info);
114 if(This->protocol_sink)
115 IInternetProtocolSink_Release(This->protocol_sink);
117 HeapFree(GetProcessHeap(), 0, This);
119 URLMON_UnlockModule();
122 return ref;
125 static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
126 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
127 DWORD grfPI, DWORD dwReserved)
129 BindProtocol *This = PROTOCOL_THIS(iface);
130 IInternetProtocol *protocol = NULL;
131 IInternetPriority *priority;
132 IServiceProvider *service_provider;
133 CLSID clsid = IID_NULL;
134 LPOLESTR clsid_str;
135 HRESULT hres;
137 TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
138 pOIBindInfo, grfPI, dwReserved);
140 if(!szUrl || !pOIProtSink || !pOIBindInfo)
141 return E_INVALIDARG;
143 hres = IInternetProtocolSink_QueryInterface(pOIProtSink, &IID_IServiceProvider,
144 (void**)&service_provider);
145 if(SUCCEEDED(hres)) {
146 /* FIXME: What's protocol CLSID here? */
147 IServiceProvider_QueryService(service_provider, &IID_IInternetProtocol,
148 &IID_IInternetProtocol, (void**)&protocol);
149 IServiceProvider_Release(service_provider);
152 if(!protocol) {
153 IClassFactory *cf;
154 IUnknown *unk;
156 hres = get_protocol_handler(szUrl, &clsid, &cf);
157 if(FAILED(hres))
158 return hres;
160 hres = IClassFactory_CreateInstance(cf, (IUnknown*)BINDINFO(This),
161 &IID_IUnknown, (void**)&unk);
162 IClassFactory_Release(cf);
163 if(FAILED(hres))
164 return hres;
166 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&protocol);
167 IUnknown_Release(unk);
168 if(FAILED(hres))
169 return hres;
172 StringFromCLSID(&clsid, &clsid_str);
173 IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_PROTOCOLCLASSID, clsid_str);
174 CoTaskMemFree(clsid_str);
176 This->protocol = protocol;
178 IInternetBindInfo_AddRef(pOIBindInfo);
179 This->bind_info = pOIBindInfo;
181 IInternetProtocolSink_AddRef(pOIProtSink);
182 This->protocol_sink = pOIProtSink;
184 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
185 if(SUCCEEDED(hres)) {
186 IInternetPriority_SetPriority(priority, This->priority);
187 IInternetPriority_Release(priority);
190 return IInternetProtocol_Start(protocol, szUrl, PROTSINK(This), BINDINFO(This), 0, 0);
193 static HRESULT WINAPI BindProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
195 BindProtocol *This = PROTOCOL_THIS(iface);
196 FIXME("(%p)->(%p)\n", This, pProtocolData);
197 return E_NOTIMPL;
200 static HRESULT WINAPI BindProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
201 DWORD dwOptions)
203 BindProtocol *This = PROTOCOL_THIS(iface);
204 FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
205 return E_NOTIMPL;
208 static HRESULT WINAPI BindProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
210 BindProtocol *This = PROTOCOL_THIS(iface);
212 TRACE("(%p)->(%08x)\n", This, dwOptions);
214 IInternetProtocol_Terminate(This->protocol, 0);
215 return S_OK;
218 static HRESULT WINAPI BindProtocol_Suspend(IInternetProtocol *iface)
220 BindProtocol *This = PROTOCOL_THIS(iface);
221 FIXME("(%p)\n", This);
222 return E_NOTIMPL;
225 static HRESULT WINAPI BindProtocol_Resume(IInternetProtocol *iface)
227 BindProtocol *This = PROTOCOL_THIS(iface);
228 FIXME("(%p)\n", This);
229 return E_NOTIMPL;
232 static HRESULT WINAPI BindProtocol_Read(IInternetProtocol *iface, void *pv,
233 ULONG cb, ULONG *pcbRead)
235 BindProtocol *This = PROTOCOL_THIS(iface);
236 ULONG read = 0;
237 HRESULT hres;
239 TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
241 hres = IInternetProtocol_Read(This->protocol, pv, cb, &read);
243 *pcbRead = read;
244 return hres;
247 static HRESULT WINAPI BindProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
248 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
250 BindProtocol *This = PROTOCOL_THIS(iface);
251 FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
252 return E_NOTIMPL;
255 static HRESULT WINAPI BindProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
257 BindProtocol *This = PROTOCOL_THIS(iface);
258 FIXME("(%p)->(%08x)\n", This, dwOptions);
259 return E_NOTIMPL;
262 static HRESULT WINAPI BindProtocol_UnlockRequest(IInternetProtocol *iface)
264 BindProtocol *This = PROTOCOL_THIS(iface);
265 FIXME("(%p)\n", This);
266 return E_NOTIMPL;
269 #undef PROTOCOL_THIS
271 static const IInternetProtocolVtbl BindProtocolVtbl = {
272 BindProtocol_QueryInterface,
273 BindProtocol_AddRef,
274 BindProtocol_Release,
275 BindProtocol_Start,
276 BindProtocol_Continue,
277 BindProtocol_Abort,
278 BindProtocol_Terminate,
279 BindProtocol_Suspend,
280 BindProtocol_Resume,
281 BindProtocol_Read,
282 BindProtocol_Seek,
283 BindProtocol_LockRequest,
284 BindProtocol_UnlockRequest
287 #define BINDINFO_THIS(iface) DEFINE_THIS(BindProtocol, InternetBindInfo, iface)
289 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface,
290 REFIID riid, void **ppv)
292 BindProtocol *This = BINDINFO_THIS(iface);
293 return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
296 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
298 BindProtocol *This = BINDINFO_THIS(iface);
299 return IBinding_AddRef(PROTOCOL(This));
302 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
304 BindProtocol *This = BINDINFO_THIS(iface);
305 return IBinding_Release(PROTOCOL(This));
308 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface,
309 DWORD *grfBINDF, BINDINFO *pbindinfo)
311 BindProtocol *This = BINDINFO_THIS(iface);
312 HRESULT hres;
314 TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
316 hres = IInternetBindInfo_GetBindInfo(This->bind_info, grfBINDF, pbindinfo);
317 if(FAILED(hres)) {
318 WARN("GetBindInfo failed: %08x\n", hres);
319 return hres;
322 *grfBINDF |= BINDF_FROMURLMON;
323 return hres;
326 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface,
327 ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
329 BindProtocol *This = BINDINFO_THIS(iface);
330 FIXME("(%p)->(%d %p %d %p)\n", This, ulStringType, ppwzStr, cEl, pcElFetched);
331 return E_NOTIMPL;
334 #undef BINDFO_THIS
336 static const IInternetBindInfoVtbl InternetBindInfoVtbl = {
337 BindInfo_QueryInterface,
338 BindInfo_AddRef,
339 BindInfo_Release,
340 BindInfo_GetBindInfo,
341 BindInfo_GetBindString
344 #define PRIORITY_THIS(iface) DEFINE_THIS(BindProtocol, InternetPriority, iface)
346 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
347 REFIID riid, void **ppv)
349 BindProtocol *This = PRIORITY_THIS(iface);
350 return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
353 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
355 BindProtocol *This = PRIORITY_THIS(iface);
356 return IInternetProtocol_AddRef(PROTOCOL(This));
359 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
361 BindProtocol *This = PRIORITY_THIS(iface);
362 return IInternetProtocol_Release(PROTOCOL(This));
365 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
367 BindProtocol *This = PRIORITY_THIS(iface);
369 TRACE("(%p)->(%d)\n", This, nPriority);
371 This->priority = nPriority;
372 return S_OK;
375 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
377 BindProtocol *This = PRIORITY_THIS(iface);
379 TRACE("(%p)->(%p)\n", This, pnPriority);
381 *pnPriority = This->priority;
382 return S_OK;
385 #undef PRIORITY_THIS
387 static const IInternetPriorityVtbl InternetPriorityVtbl = {
388 InternetPriority_QueryInterface,
389 InternetPriority_AddRef,
390 InternetPriority_Release,
391 InternetPriority_SetPriority,
392 InternetPriority_GetPriority
396 #define PROTSINK_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocolSink, iface)
398 static HRESULT WINAPI InternetProtocolSink_QueryInterface(IInternetProtocolSink *iface,
399 REFIID riid, void **ppv)
401 BindProtocol *This = PROTSINK_THIS(iface);
402 return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
405 static ULONG WINAPI InternetProtocolSink_AddRef(IInternetProtocolSink *iface)
407 BindProtocol *This = PROTSINK_THIS(iface);
408 return IInternetProtocol_AddRef(PROTOCOL(This));
411 static ULONG WINAPI InternetProtocolSink_Release(IInternetProtocolSink *iface)
413 BindProtocol *This = PROTSINK_THIS(iface);
414 return IInternetProtocol_Release(PROTOCOL(This));
417 static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface,
418 PROTOCOLDATA *pProtocolData)
420 BindProtocol *This = PROTSINK_THIS(iface);
421 FIXME("(%p)->(%p)\n", This, pProtocolData);
422 return E_NOTIMPL;
425 static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink *iface,
426 ULONG ulStatusCode, LPCWSTR szStatusText)
428 BindProtocol *This = PROTSINK_THIS(iface);
430 TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));
432 switch(ulStatusCode) {
433 case BINDSTATUS_SENDINGREQUEST:
434 return IInternetProtocolSink_ReportProgress(This->protocol_sink,
435 ulStatusCode, NULL);
436 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
437 return IInternetProtocolSink_ReportProgress(This->protocol_sink,
438 ulStatusCode, szStatusText);
439 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
440 return IInternetProtocolSink_ReportProgress(This->protocol_sink,
441 BINDSTATUS_MIMETYPEAVAILABLE, szStatusText);
442 default:
443 FIXME("unsupported ulStatusCode %u\n", ulStatusCode);
446 return E_NOTIMPL;
449 static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *iface,
450 DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
452 BindProtocol *This = PROTSINK_THIS(iface);
454 TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
456 return S_OK;
459 static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *iface,
460 HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
462 BindProtocol *This = PROTSINK_THIS(iface);
464 TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
466 return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult);
469 #undef PROTSINK_THIS
471 static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = {
472 InternetProtocolSink_QueryInterface,
473 InternetProtocolSink_AddRef,
474 InternetProtocolSink_Release,
475 InternetProtocolSink_Switch,
476 InternetProtocolSink_ReportProgress,
477 InternetProtocolSink_ReportData,
478 InternetProtocolSink_ReportResult
481 HRESULT create_binding_protocol(LPCWSTR url, IInternetProtocol **protocol)
483 BindProtocol *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(BindProtocol));
485 ret->lpInternetProtocolVtbl = &BindProtocolVtbl;
486 ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl;
487 ret->lpInternetPriorityVtbl = &InternetPriorityVtbl;
488 ret->lpInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl;
490 ret->ref = 1;
491 ret->protocol = NULL;
492 ret->bind_info = NULL;
493 ret->protocol_sink = NULL;
494 ret->priority = 0;
496 URLMON_LockModule();
498 *protocol = PROTOCOL(ret);
499 return S_OK;