push 67767ac9acc8c043474e63e8797e1c6852e614a9
[wine/hacks.git] / dlls / urlmon / bindprot.c
blob13a3b0a0838f1cdda33304ed548408117f628316
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 "urlmon_main.h"
20 #include "wine/debug.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
24 typedef struct {
25 const IInternetProtocolVtbl *lpInternetProtocolVtbl;
26 const IInternetBindInfoVtbl *lpInternetBindInfoVtbl;
27 const IInternetPriorityVtbl *lpInternetPriorityVtbl;
28 const IInternetProtocolSinkVtbl *lpInternetProtocolSinkVtbl;
30 LONG ref;
32 IInternetProtocol *protocol;
33 IInternetBindInfo *bind_info;
34 IInternetProtocolSink *protocol_sink;
36 LONG priority;
37 } BindProtocol;
39 #define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
40 #define BINDINFO(x) ((IInternetBindInfo*) &(x)->lpInternetBindInfoVtbl)
41 #define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
42 #define PROTSINK(x) ((IInternetProtocolSink*) &(x)->lpInternetProtocolSinkVtbl)
44 #define PROTOCOL_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocol, iface)
46 static HRESULT WINAPI BindProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
48 BindProtocol *This = PROTOCOL_THIS(iface);
50 *ppv = NULL;
51 if(IsEqualGUID(&IID_IUnknown, riid)) {
52 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
53 *ppv = PROTOCOL(This);
54 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
55 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
56 *ppv = PROTOCOL(This);
57 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
58 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
59 *ppv = PROTOCOL(This);
60 }else if(IsEqualGUID(&IID_IInternetBindInfo, riid)) {
61 TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This, ppv);
62 *ppv = BINDINFO(This);
63 }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
64 TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
65 *ppv = PRIORITY(This);
66 }else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
67 FIXME("(%p)->(IID_IAuthenticate %p)\n", This, ppv);
68 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
69 FIXME("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
70 }else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
71 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
72 *ppv = PROTSINK(This);
75 if(*ppv) {
76 IInternetProtocol_AddRef(iface);
77 return S_OK;
80 WARN("not supported interface %s\n", debugstr_guid(riid));
81 return E_NOINTERFACE;
84 static ULONG WINAPI BindProtocol_AddRef(IInternetProtocol *iface)
86 BindProtocol *This = PROTOCOL_THIS(iface);
87 LONG ref = InterlockedIncrement(&This->ref);
88 TRACE("(%p) ref=%d\n", This, ref);
89 return ref;
92 static ULONG WINAPI BindProtocol_Release(IInternetProtocol *iface)
94 BindProtocol *This = PROTOCOL_THIS(iface);
95 LONG ref = InterlockedDecrement(&This->ref);
97 TRACE("(%p) ref=%d\n", This, ref);
99 if(!ref) {
100 if(This->protocol)
101 IInternetProtocol_Release(This->protocol);
102 if(This->bind_info)
103 IInternetBindInfo_Release(This->bind_info);
104 if(This->protocol_sink)
105 IInternetProtocolSink_Release(This->protocol_sink);
107 heap_free(This);
109 URLMON_UnlockModule();
112 return ref;
115 static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
116 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
117 DWORD grfPI, DWORD dwReserved)
119 BindProtocol *This = PROTOCOL_THIS(iface);
120 IInternetProtocol *protocol = NULL;
121 IInternetPriority *priority;
122 IServiceProvider *service_provider;
123 CLSID clsid = IID_NULL;
124 LPOLESTR clsid_str;
125 HRESULT hres;
127 TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
128 pOIBindInfo, grfPI, dwReserved);
130 if(!szUrl || !pOIProtSink || !pOIBindInfo)
131 return E_INVALIDARG;
133 hres = IInternetProtocolSink_QueryInterface(pOIProtSink, &IID_IServiceProvider,
134 (void**)&service_provider);
135 if(SUCCEEDED(hres)) {
136 /* FIXME: What's protocol CLSID here? */
137 IServiceProvider_QueryService(service_provider, &IID_IInternetProtocol,
138 &IID_IInternetProtocol, (void**)&protocol);
139 IServiceProvider_Release(service_provider);
142 if(!protocol) {
143 IClassFactory *cf;
144 IUnknown *unk;
146 hres = get_protocol_handler(szUrl, &clsid, &cf);
147 if(FAILED(hres))
148 return hres;
150 hres = IClassFactory_CreateInstance(cf, (IUnknown*)BINDINFO(This),
151 &IID_IUnknown, (void**)&unk);
152 IClassFactory_Release(cf);
153 if(FAILED(hres))
154 return hres;
156 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&protocol);
157 IUnknown_Release(unk);
158 if(FAILED(hres))
159 return hres;
162 StringFromCLSID(&clsid, &clsid_str);
163 IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_PROTOCOLCLASSID, clsid_str);
164 CoTaskMemFree(clsid_str);
166 This->protocol = protocol;
168 IInternetBindInfo_AddRef(pOIBindInfo);
169 This->bind_info = pOIBindInfo;
171 IInternetProtocolSink_AddRef(pOIProtSink);
172 This->protocol_sink = pOIProtSink;
174 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
175 if(SUCCEEDED(hres)) {
176 IInternetPriority_SetPriority(priority, This->priority);
177 IInternetPriority_Release(priority);
180 return IInternetProtocol_Start(protocol, szUrl, PROTSINK(This), BINDINFO(This), 0, 0);
183 static HRESULT WINAPI BindProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
185 BindProtocol *This = PROTOCOL_THIS(iface);
186 FIXME("(%p)->(%p)\n", This, pProtocolData);
187 return E_NOTIMPL;
190 static HRESULT WINAPI BindProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
191 DWORD dwOptions)
193 BindProtocol *This = PROTOCOL_THIS(iface);
194 FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
195 return E_NOTIMPL;
198 static HRESULT WINAPI BindProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
200 BindProtocol *This = PROTOCOL_THIS(iface);
202 TRACE("(%p)->(%08x)\n", This, dwOptions);
204 IInternetProtocol_Terminate(This->protocol, 0);
205 return S_OK;
208 static HRESULT WINAPI BindProtocol_Suspend(IInternetProtocol *iface)
210 BindProtocol *This = PROTOCOL_THIS(iface);
211 FIXME("(%p)\n", This);
212 return E_NOTIMPL;
215 static HRESULT WINAPI BindProtocol_Resume(IInternetProtocol *iface)
217 BindProtocol *This = PROTOCOL_THIS(iface);
218 FIXME("(%p)\n", This);
219 return E_NOTIMPL;
222 static HRESULT WINAPI BindProtocol_Read(IInternetProtocol *iface, void *pv,
223 ULONG cb, ULONG *pcbRead)
225 BindProtocol *This = PROTOCOL_THIS(iface);
226 ULONG read = 0;
227 HRESULT hres;
229 TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
231 hres = IInternetProtocol_Read(This->protocol, pv, cb, &read);
233 *pcbRead = read;
234 return hres;
237 static HRESULT WINAPI BindProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
238 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
240 BindProtocol *This = PROTOCOL_THIS(iface);
241 FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
242 return E_NOTIMPL;
245 static HRESULT WINAPI BindProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
247 BindProtocol *This = PROTOCOL_THIS(iface);
248 FIXME("(%p)->(%08x)\n", This, dwOptions);
249 return E_NOTIMPL;
252 static HRESULT WINAPI BindProtocol_UnlockRequest(IInternetProtocol *iface)
254 BindProtocol *This = PROTOCOL_THIS(iface);
255 FIXME("(%p)\n", This);
256 return E_NOTIMPL;
259 #undef PROTOCOL_THIS
261 static const IInternetProtocolVtbl BindProtocolVtbl = {
262 BindProtocol_QueryInterface,
263 BindProtocol_AddRef,
264 BindProtocol_Release,
265 BindProtocol_Start,
266 BindProtocol_Continue,
267 BindProtocol_Abort,
268 BindProtocol_Terminate,
269 BindProtocol_Suspend,
270 BindProtocol_Resume,
271 BindProtocol_Read,
272 BindProtocol_Seek,
273 BindProtocol_LockRequest,
274 BindProtocol_UnlockRequest
277 #define BINDINFO_THIS(iface) DEFINE_THIS(BindProtocol, InternetBindInfo, iface)
279 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface,
280 REFIID riid, void **ppv)
282 BindProtocol *This = BINDINFO_THIS(iface);
283 return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
286 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
288 BindProtocol *This = BINDINFO_THIS(iface);
289 return IBinding_AddRef(PROTOCOL(This));
292 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
294 BindProtocol *This = BINDINFO_THIS(iface);
295 return IBinding_Release(PROTOCOL(This));
298 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface,
299 DWORD *grfBINDF, BINDINFO *pbindinfo)
301 BindProtocol *This = BINDINFO_THIS(iface);
302 HRESULT hres;
304 TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
306 hres = IInternetBindInfo_GetBindInfo(This->bind_info, grfBINDF, pbindinfo);
307 if(FAILED(hres)) {
308 WARN("GetBindInfo failed: %08x\n", hres);
309 return hres;
312 *grfBINDF |= BINDF_FROMURLMON;
313 return hres;
316 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface,
317 ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
319 BindProtocol *This = BINDINFO_THIS(iface);
320 FIXME("(%p)->(%d %p %d %p)\n", This, ulStringType, ppwzStr, cEl, pcElFetched);
321 return E_NOTIMPL;
324 #undef BINDFO_THIS
326 static const IInternetBindInfoVtbl InternetBindInfoVtbl = {
327 BindInfo_QueryInterface,
328 BindInfo_AddRef,
329 BindInfo_Release,
330 BindInfo_GetBindInfo,
331 BindInfo_GetBindString
334 #define PRIORITY_THIS(iface) DEFINE_THIS(BindProtocol, InternetPriority, iface)
336 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
337 REFIID riid, void **ppv)
339 BindProtocol *This = PRIORITY_THIS(iface);
340 return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
343 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
345 BindProtocol *This = PRIORITY_THIS(iface);
346 return IInternetProtocol_AddRef(PROTOCOL(This));
349 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
351 BindProtocol *This = PRIORITY_THIS(iface);
352 return IInternetProtocol_Release(PROTOCOL(This));
355 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
357 BindProtocol *This = PRIORITY_THIS(iface);
359 TRACE("(%p)->(%d)\n", This, nPriority);
361 This->priority = nPriority;
362 return S_OK;
365 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
367 BindProtocol *This = PRIORITY_THIS(iface);
369 TRACE("(%p)->(%p)\n", This, pnPriority);
371 *pnPriority = This->priority;
372 return S_OK;
375 #undef PRIORITY_THIS
377 static const IInternetPriorityVtbl InternetPriorityVtbl = {
378 InternetPriority_QueryInterface,
379 InternetPriority_AddRef,
380 InternetPriority_Release,
381 InternetPriority_SetPriority,
382 InternetPriority_GetPriority
386 #define PROTSINK_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocolSink, iface)
388 static HRESULT WINAPI InternetProtocolSink_QueryInterface(IInternetProtocolSink *iface,
389 REFIID riid, void **ppv)
391 BindProtocol *This = PROTSINK_THIS(iface);
392 return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
395 static ULONG WINAPI InternetProtocolSink_AddRef(IInternetProtocolSink *iface)
397 BindProtocol *This = PROTSINK_THIS(iface);
398 return IInternetProtocol_AddRef(PROTOCOL(This));
401 static ULONG WINAPI InternetProtocolSink_Release(IInternetProtocolSink *iface)
403 BindProtocol *This = PROTSINK_THIS(iface);
404 return IInternetProtocol_Release(PROTOCOL(This));
407 static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface,
408 PROTOCOLDATA *pProtocolData)
410 BindProtocol *This = PROTSINK_THIS(iface);
411 FIXME("(%p)->(%p)\n", This, pProtocolData);
412 return E_NOTIMPL;
415 static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink *iface,
416 ULONG ulStatusCode, LPCWSTR szStatusText)
418 BindProtocol *This = PROTSINK_THIS(iface);
420 TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));
422 switch(ulStatusCode) {
423 case BINDSTATUS_SENDINGREQUEST:
424 return IInternetProtocolSink_ReportProgress(This->protocol_sink,
425 ulStatusCode, NULL);
426 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
427 return IInternetProtocolSink_ReportProgress(This->protocol_sink,
428 ulStatusCode, szStatusText);
429 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
430 return IInternetProtocolSink_ReportProgress(This->protocol_sink,
431 BINDSTATUS_MIMETYPEAVAILABLE, szStatusText);
432 default:
433 FIXME("unsupported ulStatusCode %u\n", ulStatusCode);
436 return E_NOTIMPL;
439 static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *iface,
440 DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
442 BindProtocol *This = PROTSINK_THIS(iface);
444 TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
446 return S_OK;
449 static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *iface,
450 HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
452 BindProtocol *This = PROTSINK_THIS(iface);
454 TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
456 return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult);
459 #undef PROTSINK_THIS
461 static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = {
462 InternetProtocolSink_QueryInterface,
463 InternetProtocolSink_AddRef,
464 InternetProtocolSink_Release,
465 InternetProtocolSink_Switch,
466 InternetProtocolSink_ReportProgress,
467 InternetProtocolSink_ReportData,
468 InternetProtocolSink_ReportResult
471 HRESULT create_binding_protocol(LPCWSTR url, IInternetProtocol **protocol)
473 BindProtocol *ret = heap_alloc(sizeof(BindProtocol));
475 ret->lpInternetProtocolVtbl = &BindProtocolVtbl;
476 ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl;
477 ret->lpInternetPriorityVtbl = &InternetPriorityVtbl;
478 ret->lpInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl;
480 ret->ref = 1;
481 ret->protocol = NULL;
482 ret->bind_info = NULL;
483 ret->protocol_sink = NULL;
484 ret->priority = 0;
486 URLMON_LockModule();
488 *protocol = PROTOCOL(ret);
489 return S_OK;