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
);
25 const IInternetProtocolVtbl
*lpInternetProtocolVtbl
;
26 const IInternetBindInfoVtbl
*lpInternetBindInfoVtbl
;
27 const IInternetPriorityVtbl
*lpInternetPriorityVtbl
;
28 const IInternetProtocolSinkVtbl
*lpInternetProtocolSinkVtbl
;
32 IInternetProtocol
*protocol
;
33 IInternetBindInfo
*bind_info
;
34 IInternetProtocolSink
*protocol_sink
;
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
);
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
);
76 IInternetProtocol_AddRef(iface
);
80 WARN("not supported interface %s\n", debugstr_guid(riid
));
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
);
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
);
101 IInternetProtocol_Release(This
->protocol
);
103 IInternetBindInfo_Release(This
->bind_info
);
104 if(This
->protocol_sink
)
105 IInternetProtocolSink_Release(This
->protocol_sink
);
109 URLMON_UnlockModule();
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
;
127 TRACE("(%p)->(%s %p %p %08x %d)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
128 pOIBindInfo
, grfPI
, dwReserved
);
130 if(!szUrl
|| !pOIProtSink
|| !pOIBindInfo
)
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
);
146 hres
= get_protocol_handler(szUrl
, &clsid
, &cf
);
150 hres
= IClassFactory_CreateInstance(cf
, (IUnknown
*)BINDINFO(This
),
151 &IID_IUnknown
, (void**)&unk
);
152 IClassFactory_Release(cf
);
156 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocol
, (void**)&protocol
);
157 IUnknown_Release(unk
);
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
);
190 static HRESULT WINAPI
BindProtocol_Abort(IInternetProtocol
*iface
, HRESULT hrReason
,
193 BindProtocol
*This
= PROTOCOL_THIS(iface
);
194 FIXME("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
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);
208 static HRESULT WINAPI
BindProtocol_Suspend(IInternetProtocol
*iface
)
210 BindProtocol
*This
= PROTOCOL_THIS(iface
);
211 FIXME("(%p)\n", This
);
215 static HRESULT WINAPI
BindProtocol_Resume(IInternetProtocol
*iface
)
217 BindProtocol
*This
= PROTOCOL_THIS(iface
);
218 FIXME("(%p)\n", This
);
222 static HRESULT WINAPI
BindProtocol_Read(IInternetProtocol
*iface
, void *pv
,
223 ULONG cb
, ULONG
*pcbRead
)
225 BindProtocol
*This
= PROTOCOL_THIS(iface
);
229 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
231 hres
= IInternetProtocol_Read(This
->protocol
, pv
, cb
, &read
);
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
);
245 static HRESULT WINAPI
BindProtocol_LockRequest(IInternetProtocol
*iface
, DWORD dwOptions
)
247 BindProtocol
*This
= PROTOCOL_THIS(iface
);
248 FIXME("(%p)->(%08x)\n", This
, dwOptions
);
252 static HRESULT WINAPI
BindProtocol_UnlockRequest(IInternetProtocol
*iface
)
254 BindProtocol
*This
= PROTOCOL_THIS(iface
);
255 FIXME("(%p)\n", This
);
261 static const IInternetProtocolVtbl BindProtocolVtbl
= {
262 BindProtocol_QueryInterface
,
264 BindProtocol_Release
,
266 BindProtocol_Continue
,
268 BindProtocol_Terminate
,
269 BindProtocol_Suspend
,
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
);
304 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
306 hres
= IInternetBindInfo_GetBindInfo(This
->bind_info
, grfBINDF
, pbindinfo
);
308 WARN("GetBindInfo failed: %08x\n", hres
);
312 *grfBINDF
|= BINDF_FROMURLMON
;
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
);
326 static const IInternetBindInfoVtbl InternetBindInfoVtbl
= {
327 BindInfo_QueryInterface
,
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
;
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
;
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
);
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
,
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
);
433 FIXME("unsupported ulStatusCode %u\n", ulStatusCode
);
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
);
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
);
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
;
481 ret
->protocol
= NULL
;
482 ret
->bind_info
= NULL
;
483 ret
->protocol_sink
= NULL
;
488 *protocol
= PROTOCOL(ret
);