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
28 #include "urlmon_main.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(urlmon
);
35 const IInternetProtocolVtbl
*lpInternetProtocolVtbl
;
36 const IInternetBindInfoVtbl
*lpInternetBindInfoVtbl
;
37 const IInternetPriorityVtbl
*lpInternetPriorityVtbl
;
38 const IInternetProtocolSinkVtbl
*lpInternetProtocolSinkVtbl
;
42 IInternetProtocol
*protocol
;
43 IInternetBindInfo
*bind_info
;
44 IInternetProtocolSink
*protocol_sink
;
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
);
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
);
86 IInternetProtocol_AddRef(iface
);
90 WARN("not supported interface %s\n", debugstr_guid(riid
));
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
);
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
);
111 IInternetProtocol_Release(This
->protocol
);
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();
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
;
137 TRACE("(%p)->(%s %p %p %08x %d)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
138 pOIBindInfo
, grfPI
, dwReserved
);
140 if(!szUrl
|| !pOIProtSink
|| !pOIBindInfo
)
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
);
156 hres
= get_protocol_handler(szUrl
, &clsid
, &cf
);
160 hres
= IClassFactory_CreateInstance(cf
, (IUnknown
*)BINDINFO(This
),
161 &IID_IUnknown
, (void**)&unk
);
162 IClassFactory_Release(cf
);
166 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocol
, (void**)&protocol
);
167 IUnknown_Release(unk
);
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
);
200 static HRESULT WINAPI
BindProtocol_Abort(IInternetProtocol
*iface
, HRESULT hrReason
,
203 BindProtocol
*This
= PROTOCOL_THIS(iface
);
204 FIXME("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
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);
218 static HRESULT WINAPI
BindProtocol_Suspend(IInternetProtocol
*iface
)
220 BindProtocol
*This
= PROTOCOL_THIS(iface
);
221 FIXME("(%p)\n", This
);
225 static HRESULT WINAPI
BindProtocol_Resume(IInternetProtocol
*iface
)
227 BindProtocol
*This
= PROTOCOL_THIS(iface
);
228 FIXME("(%p)\n", This
);
232 static HRESULT WINAPI
BindProtocol_Read(IInternetProtocol
*iface
, void *pv
,
233 ULONG cb
, ULONG
*pcbRead
)
235 BindProtocol
*This
= PROTOCOL_THIS(iface
);
239 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
241 hres
= IInternetProtocol_Read(This
->protocol
, pv
, cb
, &read
);
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
);
255 static HRESULT WINAPI
BindProtocol_LockRequest(IInternetProtocol
*iface
, DWORD dwOptions
)
257 BindProtocol
*This
= PROTOCOL_THIS(iface
);
258 FIXME("(%p)->(%08x)\n", This
, dwOptions
);
262 static HRESULT WINAPI
BindProtocol_UnlockRequest(IInternetProtocol
*iface
)
264 BindProtocol
*This
= PROTOCOL_THIS(iface
);
265 FIXME("(%p)\n", This
);
271 static const IInternetProtocolVtbl BindProtocolVtbl
= {
272 BindProtocol_QueryInterface
,
274 BindProtocol_Release
,
276 BindProtocol_Continue
,
278 BindProtocol_Terminate
,
279 BindProtocol_Suspend
,
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
);
314 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
316 hres
= IInternetBindInfo_GetBindInfo(This
->bind_info
, grfBINDF
, pbindinfo
);
318 WARN("GetBindInfo failed: %08x\n", hres
);
322 *grfBINDF
|= BINDF_FROMURLMON
;
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
);
336 static const IInternetBindInfoVtbl InternetBindInfoVtbl
= {
337 BindInfo_QueryInterface
,
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
;
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
;
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
);
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
,
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
);
443 FIXME("unsupported ulStatusCode %u\n", ulStatusCode
);
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
);
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
);
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
;
491 ret
->protocol
= NULL
;
492 ret
->bind_info
= NULL
;
493 ret
->protocol_sink
= NULL
;
496 *protocol
= PROTOCOL(ret
);