Visual C++ backend for rbuild (for now just a hacked mingw backend) and related compi...
[reactos.git] / dll / win32 / urlmon / bindprot.c
1 /*
2 * Copyright 2007 Jacek Caban for CodeWeavers
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #include "urlmon_main.h"
20 #include "wine/debug.h"
21
22 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
23
24 typedef struct {
25 const IInternetProtocolVtbl *lpInternetProtocolVtbl;
26 const IInternetBindInfoVtbl *lpInternetBindInfoVtbl;
27 const IInternetPriorityVtbl *lpInternetPriorityVtbl;
28 const IServiceProviderVtbl *lpServiceProviderVtbl;
29 const IInternetProtocolSinkVtbl *lpInternetProtocolSinkVtbl;
30
31 LONG ref;
32
33 IInternetProtocol *protocol;
34 IInternetBindInfo *bind_info;
35 IInternetProtocolSink *protocol_sink;
36 IServiceProvider *service_provider;
37
38 LONG priority;
39
40 BOOL reported_result;
41 BOOL from_urlmon;
42 } BindProtocol;
43
44 #define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
45 #define BINDINFO(x) ((IInternetBindInfo*) &(x)->lpInternetBindInfoVtbl)
46 #define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
47 #define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl)
48 #define PROTSINK(x) ((IInternetProtocolSink*) &(x)->lpInternetProtocolSinkVtbl)
49
50 #define PROTOCOL_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocol, iface)
51
52 static HRESULT WINAPI BindProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
53 {
54 BindProtocol *This = PROTOCOL_THIS(iface);
55
56 *ppv = NULL;
57 if(IsEqualGUID(&IID_IUnknown, riid)) {
58 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
59 *ppv = PROTOCOL(This);
60 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
61 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
62 *ppv = PROTOCOL(This);
63 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
64 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
65 *ppv = PROTOCOL(This);
66 }else if(IsEqualGUID(&IID_IInternetBindInfo, riid)) {
67 TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This, ppv);
68 *ppv = BINDINFO(This);
69 }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
70 TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
71 *ppv = PRIORITY(This);
72 }else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
73 FIXME("(%p)->(IID_IAuthenticate %p)\n", This, ppv);
74 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
75 TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
76 *ppv = SERVPROV(This);
77 }else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
78 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
79 *ppv = PROTSINK(This);
80 }
81
82 if(*ppv) {
83 IInternetProtocol_AddRef(iface);
84 return S_OK;
85 }
86
87 WARN("not supported interface %s\n", debugstr_guid(riid));
88 return E_NOINTERFACE;
89 }
90
91 static ULONG WINAPI BindProtocol_AddRef(IInternetProtocol *iface)
92 {
93 BindProtocol *This = PROTOCOL_THIS(iface);
94 LONG ref = InterlockedIncrement(&This->ref);
95 TRACE("(%p) ref=%d\n", This, ref);
96 return ref;
97 }
98
99 static ULONG WINAPI BindProtocol_Release(IInternetProtocol *iface)
100 {
101 BindProtocol *This = PROTOCOL_THIS(iface);
102 LONG ref = InterlockedDecrement(&This->ref);
103
104 TRACE("(%p) ref=%d\n", This, ref);
105
106 if(!ref) {
107 if(This->protocol)
108 IInternetProtocol_Release(This->protocol);
109 if(This->bind_info)
110 IInternetBindInfo_Release(This->bind_info);
111
112 set_binding_sink(PROTOCOL(This), NULL);
113 heap_free(This);
114
115 URLMON_UnlockModule();
116 }
117
118 return ref;
119 }
120
121 static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
122 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
123 DWORD grfPI, DWORD dwReserved)
124 {
125 BindProtocol *This = PROTOCOL_THIS(iface);
126 IInternetProtocol *protocol = NULL;
127 IInternetPriority *priority;
128 IServiceProvider *service_provider;
129 CLSID clsid = IID_NULL;
130 LPOLESTR clsid_str;
131 HRESULT hres;
132
133 TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
134 pOIBindInfo, grfPI, dwReserved);
135
136 if(!szUrl || !pOIProtSink || !pOIBindInfo)
137 return E_INVALIDARG;
138
139 hres = IInternetProtocolSink_QueryInterface(pOIProtSink, &IID_IServiceProvider,
140 (void**)&service_provider);
141 if(SUCCEEDED(hres)) {
142 /* FIXME: What's protocol CLSID here? */
143 IServiceProvider_QueryService(service_provider, &IID_IInternetProtocol,
144 &IID_IInternetProtocol, (void**)&protocol);
145 IServiceProvider_Release(service_provider);
146 }
147
148 if(!protocol) {
149 IClassFactory *cf;
150 IUnknown *unk;
151
152 hres = get_protocol_handler(szUrl, &clsid, &cf);
153 if(FAILED(hres))
154 return hres;
155
156 if(This->from_urlmon) {
157 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocol, (void**)&protocol);
158 IClassFactory_Release(cf);
159 if(FAILED(hres))
160 return hres;
161 }else {
162 hres = IClassFactory_CreateInstance(cf, (IUnknown*)BINDINFO(This),
163 &IID_IUnknown, (void**)&unk);
164 IClassFactory_Release(cf);
165 if(FAILED(hres))
166 return hres;
167
168 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&protocol);
169 IUnknown_Release(unk);
170 if(FAILED(hres))
171 return hres;
172 }
173 }
174
175 StringFromCLSID(&clsid, &clsid_str);
176 IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_PROTOCOLCLASSID, clsid_str);
177 CoTaskMemFree(clsid_str);
178
179 This->protocol = protocol;
180
181 IInternetBindInfo_AddRef(pOIBindInfo);
182 This->bind_info = pOIBindInfo;
183
184 set_binding_sink(PROTOCOL(This), pOIProtSink);
185
186 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
187 if(SUCCEEDED(hres)) {
188 IInternetPriority_SetPriority(priority, This->priority);
189 IInternetPriority_Release(priority);
190 }
191
192 return IInternetProtocol_Start(protocol, szUrl, PROTSINK(This), BINDINFO(This), 0, 0);
193 }
194
195 static HRESULT WINAPI BindProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
196 {
197 BindProtocol *This = PROTOCOL_THIS(iface);
198
199 TRACE("(%p)->(%p)\n", This, pProtocolData);
200
201 return IInternetProtocol_Continue(This->protocol, pProtocolData);
202 }
203
204 static HRESULT WINAPI BindProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
205 DWORD dwOptions)
206 {
207 BindProtocol *This = PROTOCOL_THIS(iface);
208 FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
209 return E_NOTIMPL;
210 }
211
212 static HRESULT WINAPI BindProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
213 {
214 BindProtocol *This = PROTOCOL_THIS(iface);
215
216 TRACE("(%p)->(%08x)\n", This, dwOptions);
217
218 if(!This->reported_result)
219 return E_FAIL;
220
221 IInternetProtocol_Terminate(This->protocol, 0);
222
223 set_binding_sink(PROTOCOL(This), NULL);
224
225 if(This->bind_info) {
226 IInternetBindInfo_Release(This->bind_info);
227 This->bind_info = NULL;
228 }
229
230 return S_OK;
231 }
232
233 static HRESULT WINAPI BindProtocol_Suspend(IInternetProtocol *iface)
234 {
235 BindProtocol *This = PROTOCOL_THIS(iface);
236 FIXME("(%p)\n", This);
237 return E_NOTIMPL;
238 }
239
240 static HRESULT WINAPI BindProtocol_Resume(IInternetProtocol *iface)
241 {
242 BindProtocol *This = PROTOCOL_THIS(iface);
243 FIXME("(%p)\n", This);
244 return E_NOTIMPL;
245 }
246
247 static HRESULT WINAPI BindProtocol_Read(IInternetProtocol *iface, void *pv,
248 ULONG cb, ULONG *pcbRead)
249 {
250 BindProtocol *This = PROTOCOL_THIS(iface);
251 ULONG read = 0;
252 HRESULT hres;
253
254 TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
255
256 hres = IInternetProtocol_Read(This->protocol, pv, cb, &read);
257
258 *pcbRead = read;
259 return hres;
260 }
261
262 static HRESULT WINAPI BindProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
263 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
264 {
265 BindProtocol *This = PROTOCOL_THIS(iface);
266 FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
267 return E_NOTIMPL;
268 }
269
270 static HRESULT WINAPI BindProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
271 {
272 BindProtocol *This = PROTOCOL_THIS(iface);
273
274 TRACE("(%p)->(%08x)\n", This, dwOptions);
275
276 return IInternetProtocol_LockRequest(This->protocol, dwOptions);
277 }
278
279 static HRESULT WINAPI BindProtocol_UnlockRequest(IInternetProtocol *iface)
280 {
281 BindProtocol *This = PROTOCOL_THIS(iface);
282
283 TRACE("(%p)\n", This);
284
285 return IInternetProtocol_UnlockRequest(This->protocol);
286 }
287
288 void set_binding_sink(IInternetProtocol *bind_protocol, IInternetProtocolSink *sink)
289 {
290 BindProtocol *This = PROTOCOL_THIS(bind_protocol);
291 IInternetProtocolSink *prev_sink;
292 IServiceProvider *service_provider = NULL;
293
294 if(sink)
295 IInternetProtocolSink_AddRef(sink);
296 prev_sink = InterlockedExchangePointer((void**)&This->protocol_sink, sink);
297 if(prev_sink)
298 IInternetProtocolSink_Release(prev_sink);
299
300 if(sink)
301 IInternetProtocolSink_QueryInterface(sink, &IID_IServiceProvider, (void**)&service_provider);
302 service_provider = InterlockedExchangePointer((void**)&This->service_provider, service_provider);
303 if(service_provider)
304 IServiceProvider_Release(service_provider);
305 }
306
307 #undef PROTOCOL_THIS
308
309 static const IInternetProtocolVtbl BindProtocolVtbl = {
310 BindProtocol_QueryInterface,
311 BindProtocol_AddRef,
312 BindProtocol_Release,
313 BindProtocol_Start,
314 BindProtocol_Continue,
315 BindProtocol_Abort,
316 BindProtocol_Terminate,
317 BindProtocol_Suspend,
318 BindProtocol_Resume,
319 BindProtocol_Read,
320 BindProtocol_Seek,
321 BindProtocol_LockRequest,
322 BindProtocol_UnlockRequest
323 };
324
325 #define BINDINFO_THIS(iface) DEFINE_THIS(BindProtocol, InternetBindInfo, iface)
326
327 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface,
328 REFIID riid, void **ppv)
329 {
330 BindProtocol *This = BINDINFO_THIS(iface);
331 return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
332 }
333
334 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface)
335 {
336 BindProtocol *This = BINDINFO_THIS(iface);
337 return IBinding_AddRef(PROTOCOL(This));
338 }
339
340 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface)
341 {
342 BindProtocol *This = BINDINFO_THIS(iface);
343 return IBinding_Release(PROTOCOL(This));
344 }
345
346 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface,
347 DWORD *grfBINDF, BINDINFO *pbindinfo)
348 {
349 BindProtocol *This = BINDINFO_THIS(iface);
350 HRESULT hres;
351
352 TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
353
354 hres = IInternetBindInfo_GetBindInfo(This->bind_info, grfBINDF, pbindinfo);
355 if(FAILED(hres)) {
356 WARN("GetBindInfo failed: %08x\n", hres);
357 return hres;
358 }
359
360 *grfBINDF |= BINDF_FROMURLMON;
361 return hres;
362 }
363
364 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface,
365 ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
366 {
367 BindProtocol *This = BINDINFO_THIS(iface);
368
369 TRACE("(%p)->(%d %p %d %p)\n", This, ulStringType, ppwzStr, cEl, pcElFetched);
370
371 return IInternetBindInfo_GetBindString(This->bind_info, ulStringType, ppwzStr, cEl, pcElFetched);
372 }
373
374 #undef BINDFO_THIS
375
376 static const IInternetBindInfoVtbl InternetBindInfoVtbl = {
377 BindInfo_QueryInterface,
378 BindInfo_AddRef,
379 BindInfo_Release,
380 BindInfo_GetBindInfo,
381 BindInfo_GetBindString
382 };
383
384 #define PRIORITY_THIS(iface) DEFINE_THIS(BindProtocol, InternetPriority, iface)
385
386 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface,
387 REFIID riid, void **ppv)
388 {
389 BindProtocol *This = PRIORITY_THIS(iface);
390 return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
391 }
392
393 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface)
394 {
395 BindProtocol *This = PRIORITY_THIS(iface);
396 return IInternetProtocol_AddRef(PROTOCOL(This));
397 }
398
399 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface)
400 {
401 BindProtocol *This = PRIORITY_THIS(iface);
402 return IInternetProtocol_Release(PROTOCOL(This));
403 }
404
405 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
406 {
407 BindProtocol *This = PRIORITY_THIS(iface);
408
409 TRACE("(%p)->(%d)\n", This, nPriority);
410
411 This->priority = nPriority;
412 return S_OK;
413 }
414
415 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
416 {
417 BindProtocol *This = PRIORITY_THIS(iface);
418
419 TRACE("(%p)->(%p)\n", This, pnPriority);
420
421 *pnPriority = This->priority;
422 return S_OK;
423 }
424
425 #undef PRIORITY_THIS
426
427 static const IInternetPriorityVtbl InternetPriorityVtbl = {
428 InternetPriority_QueryInterface,
429 InternetPriority_AddRef,
430 InternetPriority_Release,
431 InternetPriority_SetPriority,
432 InternetPriority_GetPriority
433
434 };
435
436 #define PROTSINK_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocolSink, iface)
437
438 static HRESULT WINAPI BPInternetProtocolSink_QueryInterface(IInternetProtocolSink *iface,
439 REFIID riid, void **ppv)
440 {
441 BindProtocol *This = PROTSINK_THIS(iface);
442 return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
443 }
444
445 static ULONG WINAPI BPInternetProtocolSink_AddRef(IInternetProtocolSink *iface)
446 {
447 BindProtocol *This = PROTSINK_THIS(iface);
448 return IInternetProtocol_AddRef(PROTOCOL(This));
449 }
450
451 static ULONG WINAPI BPInternetProtocolSink_Release(IInternetProtocolSink *iface)
452 {
453 BindProtocol *This = PROTSINK_THIS(iface);
454 return IInternetProtocol_Release(PROTOCOL(This));
455 }
456
457 static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface,
458 PROTOCOLDATA *pProtocolData)
459 {
460 BindProtocol *This = PROTSINK_THIS(iface);
461
462 TRACE("(%p)->(%p)\n", This, pProtocolData);
463
464 TRACE("flags %x state %x data %p cb %u\n", pProtocolData->grfFlags, pProtocolData->dwState,
465 pProtocolData->pData, pProtocolData->cbData);
466
467 if(!This->protocol_sink) {
468 IInternetProtocol_Continue(This->protocol, pProtocolData);
469 return S_OK;
470 }
471
472 return IInternetProtocolSink_Switch(This->protocol_sink, pProtocolData);
473 }
474
475 static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSink *iface,
476 ULONG ulStatusCode, LPCWSTR szStatusText)
477 {
478 BindProtocol *This = PROTSINK_THIS(iface);
479
480 TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));
481
482 switch(ulStatusCode) {
483 case BINDSTATUS_FINDINGRESOURCE:
484 case BINDSTATUS_CONNECTING:
485 case BINDSTATUS_BEGINDOWNLOADDATA:
486 case BINDSTATUS_SENDINGREQUEST:
487 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
488 case BINDSTATUS_DIRECTBIND:
489 case BINDSTATUS_MIMETYPEAVAILABLE:
490 if(!This->protocol_sink)
491 return S_OK;
492 return IInternetProtocolSink_ReportProgress(This->protocol_sink,
493 ulStatusCode, szStatusText);
494
495 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
496 if(!This->protocol_sink)
497 return S_OK;
498 return IInternetProtocolSink_ReportProgress(This->protocol_sink,
499 This->from_urlmon ? BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE,
500 szStatusText);
501 default:
502 FIXME("unsupported ulStatusCode %u\n", ulStatusCode);
503 }
504
505 return E_NOTIMPL;
506 }
507
508 static HRESULT WINAPI BPInternetProtocolSink_ReportData(IInternetProtocolSink *iface,
509 DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
510 {
511 BindProtocol *This = PROTSINK_THIS(iface);
512
513 TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
514
515 if(!This->protocol_sink)
516 return S_OK;
517
518 return IInternetProtocolSink_ReportData(This->protocol_sink, grfBSCF, ulProgress, ulProgressMax);
519 }
520
521 static HRESULT WINAPI BPInternetProtocolSink_ReportResult(IInternetProtocolSink *iface,
522 HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
523 {
524 BindProtocol *This = PROTSINK_THIS(iface);
525
526 TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
527
528 if(!This->protocol_sink)
529 return E_FAIL;
530
531 This->reported_result = TRUE;
532
533 return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult);
534 }
535
536 #undef PROTSINK_THIS
537
538 static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = {
539 BPInternetProtocolSink_QueryInterface,
540 BPInternetProtocolSink_AddRef,
541 BPInternetProtocolSink_Release,
542 BPInternetProtocolSink_Switch,
543 BPInternetProtocolSink_ReportProgress,
544 BPInternetProtocolSink_ReportData,
545 BPInternetProtocolSink_ReportResult
546 };
547
548 #define SERVPROV_THIS(iface) DEFINE_THIS(BindProtocol, ServiceProvider, iface)
549
550 static HRESULT WINAPI BPServiceProvider_QueryInterface(IServiceProvider *iface,
551 REFIID riid, void **ppv)
552 {
553 BindProtocol *This = SERVPROV_THIS(iface);
554 return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
555 }
556
557 static ULONG WINAPI BPServiceProvider_AddRef(IServiceProvider *iface)
558 {
559 BindProtocol *This = SERVPROV_THIS(iface);
560 return IInternetProtocol_AddRef(PROTOCOL(This));
561 }
562
563 static ULONG WINAPI BPServiceProvider_Release(IServiceProvider *iface)
564 {
565 BindProtocol *This = SERVPROV_THIS(iface);
566 return IInternetProtocol_Release(PROTOCOL(This));
567 }
568
569 static HRESULT WINAPI BPServiceProvider_QueryService(IServiceProvider *iface,
570 REFGUID guidService, REFIID riid, void **ppv)
571 {
572 BindProtocol *This = SERVPROV_THIS(iface);
573
574 TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
575
576 if(!This->service_provider)
577 return E_NOINTERFACE;
578
579 return IServiceProvider_QueryService(This->service_provider, guidService, riid, ppv);
580 }
581
582 #undef SERVPROV_THIS
583
584 static const IServiceProviderVtbl ServiceProviderVtbl = {
585 BPServiceProvider_QueryInterface,
586 BPServiceProvider_AddRef,
587 BPServiceProvider_Release,
588 BPServiceProvider_QueryService
589 };
590
591 HRESULT create_binding_protocol(LPCWSTR url, BOOL from_urlmon, IInternetProtocol **protocol)
592 {
593 BindProtocol *ret = heap_alloc_zero(sizeof(BindProtocol));
594
595 ret->lpInternetProtocolVtbl = &BindProtocolVtbl;
596 ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl;
597 ret->lpInternetPriorityVtbl = &InternetPriorityVtbl;
598 ret->lpServiceProviderVtbl = &ServiceProviderVtbl;
599 ret->lpInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl;
600
601 ret->ref = 1;
602 ret->from_urlmon = from_urlmon;
603
604 URLMON_LockModule();
605
606 *protocol = PROTOCOL(ret);
607 return S_OK;
608 }