ReactOS  0.4.13-dev-259-g5ca9c9c
binding.c
Go to the documentation of this file.
1 /*
2  * Copyright 2005-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 #define NONAMELESSUNION
20 
21 #include "urlmon_main.h"
22 #include "winreg.h"
23 #include "shlwapi.h"
24 
25 #include "wine/debug.h"
26 
28 
29 static WCHAR cbinding_contextW[] = {'C','B','i','n','d','i','n','g',' ','C','o','n','t','e','x','t',0};
30 static WCHAR bscb_holderW[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
31 
32 typedef struct {
34 
36 
38 
41 
43 } stgmed_buf_t;
44 
45 typedef struct _stgmed_obj_t stgmed_obj_t;
46 
47 typedef struct {
48  void (*release)(stgmed_obj_t*);
49  HRESULT (*fill_stgmed)(stgmed_obj_t*,STGMEDIUM*);
50  HRESULT (*get_result)(stgmed_obj_t*,DWORD,void**);
52 
53 struct _stgmed_obj_t {
55 };
56 
57 typedef enum {
62 
63 #define BINDING_LOCKED 0x0001
64 #define BINDING_STOPPED 0x0002
65 #define BINDING_OBJAVAIL 0x0004
66 #define BINDING_ABORTED 0x0008
67 
68 typedef struct {
74 
76 
79 
81 
84 
85  BINDINFO bindinfo;
103 
105 } Binding;
106 
107 static void read_protocol_data(stgmed_buf_t *stgmed_buf)
108 {
109  BYTE buf[8192];
110  DWORD read;
111  HRESULT hres;
112 
113  do hres = IInternetProtocolEx_Read(stgmed_buf->protocol, buf, sizeof(buf), &read);
114  while(hres == S_OK);
115 }
116 
117 static void dump_BINDINFO(BINDINFO *bi)
118 {
119  static const char * const BINDINFOF_str[] = {
120  "#0",
121  "BINDINFOF_URLENCODESTGMEDDATA",
122  "BINDINFOF_URLENCODEDEXTRAINFO"
123  };
124 
125  static const char * const BINDVERB_str[] = {
126  "BINDVERB_GET",
127  "BINDVERB_POST",
128  "BINDVERB_PUT",
129  "BINDVERB_CUSTOM"
130  };
131 
132  TRACE("\n"
133  "BINDINFO = {\n"
134  " %d, %s,\n"
135  " {%d, %p, %p},\n"
136  " %s,\n"
137  " %s,\n"
138  " %s,\n"
139  " %d, %08x, %d, %d\n"
140  " {%d %p %x},\n"
141  " %s\n"
142  " %p, %d\n"
143  "}\n",
144 
145  bi->cbSize, debugstr_w(bi->szExtraInfo),
146  bi->stgmedData.tymed, bi->stgmedData.u.hGlobal, bi->stgmedData.pUnkForRelease,
147  bi->grfBindInfoF > BINDINFOF_URLENCODEDEXTRAINFO
148  ? "unknown" : BINDINFOF_str[bi->grfBindInfoF],
149  bi->dwBindVerb > BINDVERB_CUSTOM
150  ? "unknown" : BINDVERB_str[bi->dwBindVerb],
151  debugstr_w(bi->szCustomVerb),
152  bi->cbstgmedData, bi->dwOptions, bi->dwOptionsFlags, bi->dwCodePage,
153  bi->securityAttributes.nLength,
154  bi->securityAttributes.lpSecurityDescriptor,
155  bi->securityAttributes.bInheritHandle,
156  debugstr_guid(&bi->iid),
157  bi->pUnk, bi->dwReserved
158  );
159 }
160 
162 {
163  heap_free(This->mime);
164  This->mime = heap_strdupW(mime);
165 
166  if(!This->mime || !This->report_mime)
167  return;
168 
169  IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE, This->mime);
170 
171  This->clipboard_format = RegisterClipboardFormatW(This->mime);
172 }
173 
174 static void stop_binding(Binding *binding, HRESULT hres, LPCWSTR str)
175 {
176  if(binding->state & BINDING_LOCKED) {
177  IInternetProtocolEx_UnlockRequest(&binding->protocol->IInternetProtocolEx_iface);
178  binding->state &= ~BINDING_LOCKED;
179  }
180 
181  if(!(binding->state & BINDING_STOPPED)) {
182  binding->state |= BINDING_STOPPED;
183 
184  binding->hres = hres;
185  IBindStatusCallback_OnStopBinding(binding->callback, hres, str);
186  }
187 }
188 
190 {
192  DWORD res, type, size;
193  HKEY hkey;
194  int len;
195  HRESULT hres;
196 
197  static const WCHAR mime_keyW[] =
198  {'M','I','M','E','\\','D','a','t','a','b','a','s','e','\\',
199  'C','o','n','t','e','n','t',' ','T','y','p','e','\\'};
200  static const WCHAR clsidW[] = {'C','L','S','I','D',0};
201 
202  len = strlenW(mime)+1;
203  key_name = heap_alloc(sizeof(mime_keyW) + len*sizeof(WCHAR));
204  memcpy(key_name, mime_keyW, sizeof(mime_keyW));
205  strcpyW(key_name + ARRAY_SIZE(mime_keyW), mime);
206 
209  if(res != ERROR_SUCCESS) {
210  WARN("Could not open MIME key: %x\n", res);
211  return NULL;
212  }
213 
214  size = 50*sizeof(WCHAR);
215  ret = heap_alloc(size);
216  res = RegQueryValueExW(hkey, clsidW, NULL, &type, (LPBYTE)ret, &size);
217  RegCloseKey(hkey);
218  if(res != ERROR_SUCCESS) {
219  WARN("Could not get CLSID: %08x\n", res);
220  heap_free(ret);
221  return NULL;
222  }
223 
225  if(FAILED(hres)) {
226  WARN("Could not parse CLSID: %08x\n", hres);
227  heap_free(ret);
228  return NULL;
229  }
230 
231  return ret;
232 }
233 
234 static void load_doc_mon(Binding *binding, IPersistMoniker *persist)
235 {
236  IBindCtx *bctx;
237  HRESULT hres;
238 
239  hres = CreateAsyncBindCtxEx(binding->bctx, 0, NULL, NULL, &bctx, 0);
240  if(FAILED(hres)) {
241  WARN("CreateAsyncBindCtxEx failed: %08x\n", hres);
242  return;
243  }
244 
245  IBindCtx_RevokeObjectParam(bctx, bscb_holderW);
246  IBindCtx_RegisterObjectParam(bctx, cbinding_contextW, (IUnknown*)&binding->IBinding_iface);
247 
248  hres = IPersistMoniker_Load(persist, binding->download_state == END_DOWNLOAD, binding->mon, bctx, 0x12);
249  IBindCtx_RevokeObjectParam(bctx, cbinding_contextW);
250  IBindCtx_Release(bctx);
251  if(FAILED(hres))
252  FIXME("Load failed: %08x\n", hres);
253 }
254 
255 static HRESULT create_mime_object(Binding *binding, const CLSID *clsid, LPCWSTR clsid_str)
256 {
257  IPersistMoniker *persist;
258  HRESULT hres;
259 
260  hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
261  &binding->iid, (void**)&binding->obj);
262  if(FAILED(hres)) {
263  WARN("CoCreateInstance failed: %08x\n", hres);
264  return INET_E_CANNOT_INSTANTIATE_OBJECT;
265  }
266 
267  binding->state |= BINDING_OBJAVAIL;
268 
269  hres = IUnknown_QueryInterface(binding->obj, &IID_IPersistMoniker, (void**)&persist);
270  if(SUCCEEDED(hres)) {
271  IMonikerProp *prop;
272 
273  hres = IPersistMoniker_QueryInterface(persist, &IID_IMonikerProp, (void**)&prop);
274  if(SUCCEEDED(hres)) {
275  IMonikerProp_PutProperty(prop, MIMETYPEPROP, binding->mime);
276  IMonikerProp_PutProperty(prop, CLASSIDPROP, clsid_str);
277  IMonikerProp_Release(prop);
278  }
279 
280  load_doc_mon(binding, persist);
281 
282  IPersistMoniker_Release(persist);
283  }else {
284  FIXME("Could not get IPersistMoniker: %08x\n", hres);
285  /* FIXME: Try query IPersistFile */
286  }
287 
288  IBindStatusCallback_OnObjectAvailable(binding->callback, &binding->iid, binding->obj);
289 
290  return S_OK;
291 }
292 
293 static void create_object(Binding *binding)
294 {
295  LPWSTR clsid_str;
296  CLSID clsid;
297  HRESULT hres;
298 
299  if(!binding->mime) {
300  FIXME("MIME not available\n");
301  return;
302  }
303 
304  if((clsid_str = get_mime_clsid(binding->mime, &clsid)))
305  IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_CLASSIDAVAILABLE, clsid_str);
306 
307  IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_BEGINSYNCOPERATION, NULL);
308 
309  if(clsid_str) {
310  hres = create_mime_object(binding, &clsid, clsid_str);
311  heap_free(clsid_str);
312  }else {
313  FIXME("Could not find object for MIME %s\n", debugstr_w(binding->mime));
315  }
316 
317  IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_ENDSYNCOPERATION, NULL);
318  binding->clsid = CLSID_NULL;
319 
320  stop_binding(binding, hres, NULL);
321  if(FAILED(hres))
322  IInternetProtocolEx_Terminate(&binding->protocol->IInternetProtocolEx_iface, 0);
323 }
324 
326 {
327  heap_free(This->stgmed_buf->cache_file);
328  This->stgmed_buf->cache_file = heap_strdupW(file_name);
329 
330  if(This->use_cache_file) {
333  if(This->stgmed_buf->file == INVALID_HANDLE_VALUE)
334  WARN("CreateFile failed: %u\n", GetLastError());
335  }
336 }
337 
339 {
340  return CONTAINING_RECORD(iface, stgmed_buf_t, IUnknown_iface);
341 }
342 
344 {
346 
347  *ppv = NULL;
348 
349  if(IsEqualGUID(riid, &IID_IUnknown)) {
350  TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
351 
352  *ppv = &This->IUnknown_iface;
353  IUnknown_AddRef(&This->IUnknown_iface);
354  return S_OK;
355  }
356 
357  TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
358  return E_NOINTERFACE;
359 }
360 
362 {
365 
366  TRACE("(%p) ref=%d\n", This, ref);
367 
368  return ref;
369 }
370 
372 {
375 
376  TRACE("(%p) ref=%d\n", This, ref);
377 
378  if(!ref) {
379  if(This->file != INVALID_HANDLE_VALUE)
380  CloseHandle(This->file);
381  IInternetProtocolEx_Release(This->protocol);
382  heap_free(This->cache_file);
383  heap_free(This);
384 
386  }
387 
388  return ref;
389 }
390 
391 static const IUnknownVtbl StgMedUnkVtbl = {
395 };
396 
398 {
399  stgmed_buf_t *ret = heap_alloc(sizeof(*ret));
400 
401  ret->IUnknown_iface.lpVtbl = &StgMedUnkVtbl;
402  ret->ref = 1;
403  ret->file = INVALID_HANDLE_VALUE;
404  ret->hres = S_OK;
405  ret->cache_file = NULL;
406 
407  IInternetProtocolEx_AddRef(protocol);
408  ret->protocol = protocol;
409 
411 
412  return ret;
413 }
414 
415 typedef struct {
418 
420 
423 
425 {
426  return CONTAINING_RECORD(iface, ProtocolStream, IStream_iface);
427 }
428 
430  REFIID riid, void **ppv)
431 {
433 
434  *ppv = NULL;
435 
436  if(IsEqualGUID(&IID_IUnknown, riid)) {
437  TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
438  *ppv = &This->IStream_iface;
439  }else if(IsEqualGUID(&IID_ISequentialStream, riid)) {
440  TRACE("(%p)->(IID_ISequentialStream %p)\n", This, ppv);
441  *ppv = &This->IStream_iface;
442  }else if(IsEqualGUID(&IID_IStream, riid)) {
443  TRACE("(%p)->(IID_IStream %p)\n", This, ppv);
444  *ppv = &This->IStream_iface;
445  }
446 
447  if(*ppv) {
448  IStream_AddRef(&This->IStream_iface);
449  return S_OK;
450  }
451 
452  WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
453  return E_NOINTERFACE;
454 }
455 
457 {
460 
461  TRACE("(%p) ref=%d\n", This, ref);
462 
463  return ref;
464 }
465 
467 {
470 
471  TRACE("(%p) ref=%d\n", This, ref);
472 
473  if(!ref) {
474  IUnknown_Release(&This->buf->IUnknown_iface);
475  heap_free(This);
476 
478  }
479 
480  return ref;
481 }
482 
483 static HRESULT WINAPI ProtocolStream_Read(IStream *iface, void *pv,
484  ULONG cb, ULONG *pcbRead)
485 {
487  DWORD read = 0;
488  HRESULT hres;
489 
490  TRACE("(%p)->(%p %d %p)\n", This, pv, cb, pcbRead);
491 
492  if(This->buf->file == INVALID_HANDLE_VALUE) {
493  hres = This->buf->hres = IInternetProtocolEx_Read(This->buf->protocol, (PBYTE)pv, cb, &read);
494  }else {
495  hres = ReadFile(This->buf->file, pv, cb, &read, NULL) ? S_OK : INET_E_DOWNLOAD_FAILURE;
496  }
497 
498  if (pcbRead)
499  *pcbRead = read;
500 
501  if(hres == E_PENDING)
502  return E_PENDING;
503  else if(FAILED(hres))
504  FIXME("Read failed: %08x\n", hres);
505 
506  return read ? S_OK : S_FALSE;
507 }
508 
509 static HRESULT WINAPI ProtocolStream_Write(IStream *iface, const void *pv,
510  ULONG cb, ULONG *pcbWritten)
511 {
513 
514  TRACE("(%p)->(%p %d %p)\n", This, pv, cb, pcbWritten);
515 
516  return STG_E_ACCESSDENIED;
517 }
518 
520  DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
521 {
523  LARGE_INTEGER new_pos;
524  DWORD method;
525 
526  TRACE("(%p)->(%d %08x %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
527 
528  if(This->buf->file == INVALID_HANDLE_VALUE) {
529  /* We should probably call protocol handler's Seek. */
530  FIXME("no cache file, not supported\n");
531  return E_FAIL;
532  }
533 
534  switch(dwOrigin) {
535  case STREAM_SEEK_SET:
536  method = FILE_BEGIN;
537  break;
538  case STREAM_SEEK_CUR:
540  break;
541  case STREAM_SEEK_END:
542  method = FILE_END;
543  break;
544  default:
545  WARN("Invalid origin %x\n", dwOrigin);
546  return E_FAIL;
547  }
548 
549  if(!SetFilePointerEx(This->buf->file, dlibMove, &new_pos, method)) {
550  FIXME("SetFilePointerEx failed: %u\n", GetLastError());
551  return E_FAIL;
552  }
553 
554  if(plibNewPosition)
555  plibNewPosition->QuadPart = new_pos.QuadPart;
556  return S_OK;
557 }
558 
560 {
562  FIXME("(%p)->(%d)\n", This, libNewSize.u.LowPart);
563  return E_NOTIMPL;
564 }
565 
567  ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
568 {
570  FIXME("(%p)->(%p %d %p %p)\n", This, pstm, cb.u.LowPart, pcbRead, pcbWritten);
571  return E_NOTIMPL;
572 }
573 
574 static HRESULT WINAPI ProtocolStream_Commit(IStream *iface, DWORD grfCommitFlags)
575 {
577 
578  TRACE("(%p)->(%08x)\n", This, grfCommitFlags);
579 
580  return E_NOTIMPL;
581 }
582 
584 {
586 
587  TRACE("(%p)\n", This);
588 
589  return E_NOTIMPL;
590 }
591 
593  ULARGE_INTEGER cb, DWORD dwLockType)
594 {
596  FIXME("(%p)->(%d %d %d)\n", This, libOffset.u.LowPart, cb.u.LowPart, dwLockType);
597  return E_NOTIMPL;
598 }
599 
601  ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
602 {
604  FIXME("(%p)->(%d %d %d)\n", This, libOffset.u.LowPart, cb.u.LowPart, dwLockType);
605  return E_NOTIMPL;
606 }
607 
608 static HRESULT WINAPI ProtocolStream_Stat(IStream *iface, STATSTG *pstatstg,
609  DWORD dwStatFlag)
610 {
612  TRACE("(%p)->(%p %08x)\n", This, pstatstg, dwStatFlag);
613 
614  if(!pstatstg)
615  return E_FAIL;
616 
617  memset(pstatstg, 0, sizeof(STATSTG));
618 
619  if(!(dwStatFlag&STATFLAG_NONAME) && This->buf->cache_file) {
620  pstatstg->pwcsName = CoTaskMemAlloc((lstrlenW(This->buf->cache_file)+1)*sizeof(WCHAR));
621  if(!pstatstg->pwcsName)
623 
624  lstrcpyW(pstatstg->pwcsName, This->buf->cache_file);
625  }
626 
627  pstatstg->type = STGTY_STREAM;
628  if(This->buf->file != INVALID_HANDLE_VALUE) {
629  GetFileSizeEx(This->buf->file, (PLARGE_INTEGER)&pstatstg->cbSize);
630  GetFileTime(This->buf->file, &pstatstg->ctime, &pstatstg->atime, &pstatstg->mtime);
631  if(pstatstg->cbSize.QuadPart)
632  pstatstg->grfMode = GENERIC_READ;
633  }
634 
635  return S_OK;
636 }
637 
639 {
641  FIXME("(%p)->(%p)\n", This, ppstm);
642  return E_NOTIMPL;
643 }
644 
645 static const IStreamVtbl ProtocolStreamVtbl = {
660 };
661 
663 {
665  IStream_Release(&stream->IStream_iface);
666 }
667 
669 {
671 
672  stgmed->tymed = TYMED_ISTREAM;
673  stgmed->u.pstm = &stream->IStream_iface;
674  stgmed->pUnkForRelease = &stream->buf->IUnknown_iface;
675 
676  return S_OK;
677 }
678 
680 {
682 
683  if(!(bindf & BINDF_ASYNCHRONOUS) && stream->buf->file == INVALID_HANDLE_VALUE
684  && stream->buf->hres != S_FALSE)
685  return INET_E_DATA_NOT_AVAILABLE;
686 
687  IStream_AddRef(&stream->IStream_iface);
689  return S_OK;
690 }
691 
696 };
697 
698 typedef struct {
702 
704 {
706 
707  ret->stgmed_obj.vtbl = &stgmed_stream_vtbl;
708  ret->IStream_iface.lpVtbl = &ProtocolStreamVtbl;
709  ret->ref = 1;
710 
711  IUnknown_AddRef(&buf->IUnknown_iface);
712  ret->buf = buf;
713 
715 
716  return &ret->stgmed_obj;
717 }
718 
720 {
722 
723  IUnknown_Release(&file_obj->buf->IUnknown_iface);
724  heap_free(file_obj);
725 }
726 
727 static HRESULT stgmed_file_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed)
728 {
730 
731  if(!file_obj->buf->cache_file) {
732  WARN("cache_file not set\n");
733  return INET_E_DATA_NOT_AVAILABLE;
734  }
735 
736  read_protocol_data(file_obj->buf);
737 
738  stgmed->tymed = TYMED_FILE;
739  stgmed->u.lpszFileName = file_obj->buf->cache_file;
740  stgmed->pUnkForRelease = &file_obj->buf->IUnknown_iface;
741 
742  return S_OK;
743 }
744 
746 {
747  return bindf & BINDF_ASYNCHRONOUS ? MK_S_ASYNCHRONOUS : S_OK;
748 }
749 
754 };
755 
757 {
758  stgmed_file_obj_t *ret = heap_alloc(sizeof(*ret));
759 
760  ret->stgmed_obj.vtbl = &stgmed_file_vtbl;
761 
762  IUnknown_AddRef(&buf->IUnknown_iface);
763  ret->buf = buf;
764 
765  return &ret->stgmed_obj;
766 }
767 
768 static inline Binding *impl_from_IBinding(IBinding *iface)
769 {
770  return CONTAINING_RECORD(iface, Binding, IBinding_iface);
771 }
772 
774 {
775  Binding *This = impl_from_IBinding(iface);
776 
777  *ppv = NULL;
778 
779  if(IsEqualGUID(&IID_IUnknown, riid)) {
780  TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
781  *ppv = &This->IBinding_iface;
782  }else if(IsEqualGUID(&IID_IBinding, riid)) {
783  TRACE("(%p)->(IID_IBinding %p)\n", This, ppv);
784  *ppv = &This->IBinding_iface;
785  }else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
786  TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
787  *ppv = &This->IInternetProtocolSink_iface;
788  }else if(IsEqualGUID(&IID_IInternetBindInfo, riid)) {
789  TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This, ppv);
790  *ppv = &This->IInternetBindInfo_iface;
791  }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
792  TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
793  *ppv = &This->IServiceProvider_iface;
794  }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) {
795  IWinInetInfo *wininet_info;
796  HRESULT hres;
797 
798  TRACE("(%p)->(IID_IWinInetInfo %p)\n", This, ppv);
799 
800  /* NOTE: This violidates COM rules, but tests prove that we should do it */
801  hres = IInternetProtocolEx_QueryInterface(&This->protocol->IInternetProtocolEx_iface,
802  &IID_IWinInetInfo, (void**)&wininet_info);
803  if(SUCCEEDED(hres)) {
804  IWinInetInfo_Release(wininet_info);
805  *ppv = &This->IWinInetHttpInfo_iface;
806  }
807  }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) {
808  IWinInetHttpInfo *http_info;
809  HRESULT hres;
810 
811  TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv);
812 
813  /* NOTE: This violidates COM rules, but tests prove that we should do it */
814  hres = IInternetProtocolEx_QueryInterface(&This->protocol->IInternetProtocolEx_iface,
815  &IID_IWinInetHttpInfo, (void**)&http_info);
816  if(SUCCEEDED(hres)) {
817  IWinInetHttpInfo_Release(http_info);
818  *ppv = &This->IWinInetHttpInfo_iface;
819  }
820  }
821 
822  if(*ppv) {
823  IBinding_AddRef(&This->IBinding_iface);
824  return S_OK;
825  }
826 
827  WARN("Unsupported interface %s\n", debugstr_guid(riid));
828  return E_NOINTERFACE;
829 }
830 
832 {
833  Binding *This = impl_from_IBinding(iface);
835 
836  TRACE("(%p) ref=%d\n", This, ref);
837 
838  return ref;
839 }
840 
842 {
843  Binding *This = impl_from_IBinding(iface);
845 
846  TRACE("(%p) ref=%d\n", This, ref);
847 
848  if(!ref) {
849  if(This->notif_hwnd)
850  release_notif_hwnd(This->notif_hwnd);
851  if(This->mon)
852  IMoniker_Release(This->mon);
853  if(This->callback)
854  IBindStatusCallback_Release(This->callback);
855  if(This->protocol)
856  IInternetProtocolEx_Release(&This->protocol->IInternetProtocolEx_iface);
857  if(This->service_provider)
858  IServiceProvider_Release(This->service_provider);
859  if(This->stgmed_buf)
860  IUnknown_Release(&This->stgmed_buf->IUnknown_iface);
861  if(This->stgmed_obj)
862  This->stgmed_obj->vtbl->release(This->stgmed_obj);
863  if(This->obj)
864  IUnknown_Release(This->obj);
865  if(This->bctx)
866  IBindCtx_Release(This->bctx);
867 
868  ReleaseBindInfo(&This->bindinfo);
869  This->section.DebugInfo->Spare[0] = 0;
870  DeleteCriticalSection(&This->section);
871  SysFreeString(This->url);
872  heap_free(This->mime);
873  heap_free(This->redirect_url);
874  heap_free(This);
875 
877  }
878 
879  return ref;
880 }
881 
883 {
884  Binding *This = impl_from_IBinding(iface);
885  HRESULT hres;
886 
887  TRACE("(%p)\n", This);
888 
889  if(This->state & BINDING_ABORTED)
890  return E_FAIL;
891 
892  hres = IInternetProtocolEx_Abort(&This->protocol->IInternetProtocolEx_iface, E_ABORT,
893  ERROR_SUCCESS);
894  if(FAILED(hres))
895  return hres;
896 
897  This->state |= BINDING_ABORTED;
898  return S_OK;
899 }
900 
902 {
903  Binding *This = impl_from_IBinding(iface);
904  FIXME("(%p)\n", This);
905  return E_NOTIMPL;
906 }
907 
909 {
910  Binding *This = impl_from_IBinding(iface);
911  FIXME("(%p)\n", This);
912  return E_NOTIMPL;
913 }
914 
915 static HRESULT WINAPI Binding_SetPriority(IBinding *iface, LONG nPriority)
916 {
917  Binding *This = impl_from_IBinding(iface);
918  FIXME("(%p)->(%d)\n", This, nPriority);
919  return E_NOTIMPL;
920 }
921 
922 static HRESULT WINAPI Binding_GetPriority(IBinding *iface, LONG *pnPriority)
923 {
924  Binding *This = impl_from_IBinding(iface);
925  FIXME("(%p)->(%p)\n", This, pnPriority);
926  return E_NOTIMPL;
927 }
928 
929 static HRESULT WINAPI Binding_GetBindResult(IBinding *iface, CLSID *pclsidProtocol,
930  DWORD *pdwResult, LPOLESTR *pszResult, DWORD *pdwReserved)
931 {
932  Binding *This = impl_from_IBinding(iface);
933 
934  TRACE("(%p)->(%p %p %p %p)\n", This, pclsidProtocol, pdwResult, pszResult, pdwReserved);
935 
936  if(!pdwResult || !pszResult || pdwReserved)
937  return E_INVALIDARG;
938 
939  if(!(This->state & BINDING_STOPPED)) {
940  *pclsidProtocol = CLSID_NULL;
941  *pdwResult = 0;
942  *pszResult = NULL;
943  return S_OK;
944  }
945 
946  *pclsidProtocol = This->hres==S_OK ? CLSID_NULL : This->clsid;
947  *pdwResult = This->hres;
948  *pszResult = NULL;
949  return S_OK;
950 }
951 
952 static const IBindingVtbl BindingVtbl = {
962 };
963 
965 {
966  IBinding *binding;
967  IUnknown *unk;
968  HRESULT hres;
969 
970  hres = IBindCtx_GetObjectParam(bctx, cbinding_contextW, &unk);
971  if(FAILED(hres))
972  return NULL;
973 
974  hres = IUnknown_QueryInterface(unk, &IID_IBinding, (void**)&binding);
975  IUnknown_Release(unk);
976  if(FAILED(hres))
977  return NULL;
978 
979  if (binding->lpVtbl != &BindingVtbl)
980  return NULL;
981  return impl_from_IBinding(binding);
982 }
983 
985 {
986  return CONTAINING_RECORD(iface, Binding, IInternetProtocolSink_iface);
987 }
988 
990  REFIID riid, void **ppv)
991 {
993  return IBinding_QueryInterface(&This->IBinding_iface, riid, ppv);
994 }
995 
997 {
999  return IBinding_AddRef(&This->IBinding_iface);
1000 }
1001 
1003 {
1005  return IBinding_Release(&This->IBinding_iface);
1006 }
1007 
1009  PROTOCOLDATA *pProtocolData)
1010 {
1012 
1013  WARN("(%p)->(%p)\n", This, pProtocolData);
1014 
1015  return E_FAIL;
1016 }
1017 
1018 static void on_progress(Binding *This, ULONG progress, ULONG progress_max,
1019  ULONG status_code, LPCWSTR status_text)
1020 {
1021  IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
1022  status_code, status_text);
1023 }
1024 
1026  ULONG ulStatusCode, LPCWSTR szStatusText)
1027 {
1029 
1030  TRACE("(%p)->(%s %s)\n", This, debugstr_bindstatus(ulStatusCode), debugstr_w(szStatusText));
1031 
1032  switch(ulStatusCode) {
1033  case BINDSTATUS_FINDINGRESOURCE:
1034  on_progress(This, 0, 0, BINDSTATUS_FINDINGRESOURCE, szStatusText);
1035  break;
1036  case BINDSTATUS_CONNECTING:
1037  on_progress(This, 0, 0, BINDSTATUS_CONNECTING, szStatusText);
1038  break;
1039  case BINDSTATUS_REDIRECTING:
1040  heap_free(This->redirect_url);
1041  This->redirect_url = heap_strdupW(szStatusText);
1042  on_progress(This, 0, 0, BINDSTATUS_REDIRECTING, szStatusText);
1043  break;
1044  case BINDSTATUS_BEGINDOWNLOADDATA:
1045  break;
1046  case BINDSTATUS_SENDINGREQUEST:
1047  on_progress(This, 0, 0, BINDSTATUS_SENDINGREQUEST, szStatusText);
1048  break;
1049  case BINDSTATUS_PROTOCOLCLASSID:
1050  CLSIDFromString(szStatusText, &This->clsid);
1051  break;
1052  case BINDSTATUS_MIMETYPEAVAILABLE:
1053  case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
1054  mime_available(This, szStatusText);
1055  break;
1056  case BINDSTATUS_CACHEFILENAMEAVAILABLE:
1057  cache_file_available(This, szStatusText);
1058  break;
1059  case BINDSTATUS_DECODING:
1060  IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_DECODING, szStatusText);
1061  break;
1062  case BINDSTATUS_LOADINGMIMEHANDLER:
1063  on_progress(This, 0, 0, BINDSTATUS_LOADINGMIMEHANDLER, szStatusText);
1064  break;
1065  case BINDSTATUS_DIRECTBIND: /* FIXME: Handle BINDSTATUS_DIRECTBIND in BindProtocol */
1066  This->report_mime = FALSE;
1067  break;
1068  case BINDSTATUS_ACCEPTRANGES:
1069  break;
1070  default:
1071  FIXME("Unhandled status code %d\n", ulStatusCode);
1072  return E_NOTIMPL;
1073  };
1074 
1075  return S_OK;
1076 }
1077 
1078 static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progress_max)
1079 {
1080  FORMATETC formatetc = {0, NULL, 1, -1, TYMED_ISTREAM};
1081  BOOL sent_begindownloaddata = FALSE;
1082 
1083  TRACE("(%p)->(%d %u %u)\n", This, bscf, progress, progress_max);
1084 
1085  if(This->download_state == END_DOWNLOAD || (This->state & BINDING_ABORTED)) {
1086  read_protocol_data(This->stgmed_buf);
1087  return;
1088  }
1089 
1090  if(This->state & BINDING_STOPPED)
1091  return;
1092 
1093  if(This->stgmed_buf->file != INVALID_HANDLE_VALUE)
1094  read_protocol_data(This->stgmed_buf);
1095 
1096  if(This->download_state == BEFORE_DOWNLOAD) {
1097  This->download_state = DOWNLOADING;
1098  sent_begindownloaddata = TRUE;
1099  IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
1100  BINDSTATUS_BEGINDOWNLOADDATA, This->url);
1101 
1102  if(This->stgmed_buf->cache_file)
1103  IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
1104  BINDSTATUS_CACHEFILENAMEAVAILABLE, This->stgmed_buf->cache_file);
1105  }
1106 
1107  if(This->stgmed_buf->hres == S_FALSE || (bscf & BSCF_LASTDATANOTIFICATION)) {
1108  This->download_state = END_DOWNLOAD;
1109  IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
1110  BINDSTATUS_ENDDOWNLOADDATA, This->url);
1111  }else if(!sent_begindownloaddata) {
1112  IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
1113  BINDSTATUS_DOWNLOADINGDATA, This->url);
1114  }
1115 
1116  if(This->state & (BINDING_STOPPED|BINDING_ABORTED))
1117  return;
1118 
1119  if(This->to_object) {
1120  if(!(This->state & BINDING_OBJAVAIL)) {
1121  IBinding_AddRef(&This->IBinding_iface);
1123  IBinding_Release(&This->IBinding_iface);
1124  }
1125  }else {
1126  STGMEDIUM stgmed;
1127  HRESULT hres;
1128 
1129  if(!(This->state & BINDING_LOCKED)) {
1130  HRESULT hres = IInternetProtocolEx_LockRequest(
1131  &This->protocol->IInternetProtocolEx_iface, 0);
1132  if(SUCCEEDED(hres))
1133  This->state |= BINDING_LOCKED;
1134  }
1135 
1136  hres = This->stgmed_obj->vtbl->fill_stgmed(This->stgmed_obj, &stgmed);
1137  if(FAILED(hres)) {
1139  return;
1140  }
1141 
1142  formatetc.tymed = stgmed.tymed;
1143  formatetc.cfFormat = This->clipboard_format;
1144 
1145  hres = IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress,
1146  &formatetc, &stgmed);
1147  if(hres != S_OK) {
1148  if(This->download_state != END_DOWNLOAD) {
1149  This->download_state = END_DOWNLOAD;
1150  IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
1151  BINDSTATUS_ENDDOWNLOADDATA, This->url);
1152  }
1153 
1154  WARN("OnDataAvailable returned %x\n", hres);
1156  return;
1157  }
1158 
1159  if(This->download_state == END_DOWNLOAD)
1161  }
1162 }
1163 
1165  DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
1166 {
1168 
1169  TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
1170 
1171  report_data(This, grfBSCF, ulProgress, ulProgressMax);
1172  return S_OK;
1173 }
1174 
1176  HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
1177 {
1179 
1180  TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
1181 
1182  stop_binding(This, hrResult, szResult);
1183 
1184  IInternetProtocolEx_Terminate(&This->protocol->IInternetProtocolEx_iface, 0);
1185  return S_OK;
1186 }
1187 
1188 static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = {
1196 };
1197 
1199 {
1200  return CONTAINING_RECORD(iface, Binding, IInternetBindInfo_iface);
1201 }
1202 
1204  REFIID riid, void **ppv)
1205 {
1207  return IBinding_QueryInterface(&This->IBinding_iface, riid, ppv);
1208 }
1209 
1211 {
1213  return IBinding_AddRef(&This->IBinding_iface);
1214 }
1215 
1217 {
1219  return IBinding_Release(&This->IBinding_iface);
1220 }
1221 
1223  DWORD *grfBINDF, BINDINFO *pbindinfo)
1224 {
1226 
1227  TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
1228 
1229  *grfBINDF = This->bindf;
1230  return CopyBindInfo(&This->bindinfo, pbindinfo);
1231 }
1232 
1234  ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
1235 {
1237 
1238  TRACE("(%p)->(%d %p %d %p)\n", This, ulStringType, ppwzStr, cEl, pcElFetched);
1239 
1240  switch(ulStringType) {
1241  case BINDSTRING_ACCEPT_MIMES: {
1242  static const WCHAR wszMimes[] = {'*','/','*',0};
1243 
1244  if(!ppwzStr || !pcElFetched)
1245  return E_INVALIDARG;
1246 
1247  ppwzStr[0] = CoTaskMemAlloc(sizeof(wszMimes));
1248  memcpy(ppwzStr[0], wszMimes, sizeof(wszMimes));
1249  *pcElFetched = 1;
1250  return S_OK;
1251  }
1252  case BINDSTRING_USER_AGENT: {
1253  IInternetBindInfo *bindinfo = NULL;
1254  HRESULT hres;
1255 
1256  hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IInternetBindInfo,
1257  (void**)&bindinfo);
1258  if(FAILED(hres))
1259  return hres;
1260 
1261  hres = IInternetBindInfo_GetBindString(bindinfo, ulStringType, ppwzStr,
1262  cEl, pcElFetched);
1263  IInternetBindInfo_Release(bindinfo);
1264 
1265  return hres;
1266  }
1267  case BINDSTRING_URL: {
1268  DWORD size = (SysStringLen(This->url)+1) * sizeof(WCHAR);
1269 
1270  if(!ppwzStr || !pcElFetched)
1271  return E_INVALIDARG;
1272 
1273  *ppwzStr = CoTaskMemAlloc(size);
1274  memcpy(*ppwzStr, This->url, size);
1275  *pcElFetched = 1;
1276  return S_OK;
1277  }
1278  }
1279 
1280  FIXME("not supported string type %d\n", ulStringType);
1281  return E_NOTIMPL;
1282 }
1283 
1284 static const IInternetBindInfoVtbl InternetBindInfoVtbl = {
1290 };
1291 
1293 {
1294  return CONTAINING_RECORD(iface, Binding, IWinInetHttpInfo_iface);
1295 }
1296 
1298 {
1300  return IBinding_QueryInterface(&This->IBinding_iface, riid, ppv);
1301 }
1302 
1304 {
1306  return IBinding_AddRef(&This->IBinding_iface);
1307 }
1308 
1310 {
1312  return IBinding_Release(&This->IBinding_iface);
1313 }
1314 
1316  void *pBuffer, DWORD *pcbBuffer)
1317 {
1319  IWinInetInfo *wininet_info;
1320  HRESULT hres;
1321 
1322  TRACE("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer);
1323 
1324  hres = IInternetProtocolEx_QueryInterface(&This->protocol->IInternetProtocolEx_iface,
1325  &IID_IWinInetInfo, (void**)&wininet_info);
1326  if(FAILED(hres))
1327  return E_FAIL;
1328 
1329  hres = IWinInetInfo_QueryOption(wininet_info, dwOption, pBuffer, pcbBuffer);
1330  IWinInetInfo_Release(wininet_info);
1331  return hres;
1332 }
1333 
1335  void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved)
1336 {
1338  IWinInetHttpInfo *http_info;
1339  HRESULT hres;
1340 
1341  TRACE("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
1342 
1343  hres = IInternetProtocolEx_QueryInterface(&This->protocol->IInternetProtocolEx_iface,
1344  &IID_IWinInetHttpInfo, (void**)&http_info);
1345  if(FAILED(hres))
1346  return E_FAIL;
1347 
1348  hres = IWinInetHttpInfo_QueryInfo(http_info, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved);
1349  IWinInetHttpInfo_Release(http_info);
1350  return hres;
1351 }
1352 
1353 static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = {
1359 };
1360 
1362 {
1363  return CONTAINING_RECORD(iface, Binding, IServiceProvider_iface);
1364 }
1365 
1367  REFIID riid, void **ppv)
1368 {
1370  return IBinding_QueryInterface(&This->IBinding_iface, riid, ppv);
1371 }
1372 
1374 {
1376  return IBinding_AddRef(&This->IBinding_iface);
1377 }
1378 
1380 {
1382  return IBinding_Release(&This->IBinding_iface);
1383 }
1384 
1386  REFGUID guidService, REFIID riid, void **ppv)
1387 {
1389  HRESULT hres;
1390 
1391  TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
1392 
1393  if(This->service_provider) {
1394  hres = IServiceProvider_QueryService(This->service_provider, guidService,
1395  riid, ppv);
1396  if(SUCCEEDED(hres))
1397  return hres;
1398  }
1399 
1400  WARN("unknown service %s\n", debugstr_guid(guidService));
1401  return E_NOINTERFACE;
1402 }
1403 
1404 static const IServiceProviderVtbl ServiceProviderVtbl = {
1409 };
1410 
1412 {
1413  IUnknown *unk;
1414  HRESULT hres;
1415 
1416  hres = IBindCtx_GetObjectParam(pbc, bscb_holderW, &unk);
1417  if(FAILED(hres))
1419 
1420  hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)callback);
1421  IUnknown_Release(unk);
1422  return hres;
1423 }
1424 
1426 {
1427  DWORD scheme;
1428  HRESULT hres;
1429 
1430  hres = IUri_GetScheme(uri, &scheme);
1431  if(FAILED(hres))
1432  return FALSE;
1433 
1434  switch(scheme) {
1435  case URL_SCHEME_FILE:
1436  case URL_SCHEME_FTP:
1437  case URL_SCHEME_GOPHER:
1438  case URL_SCHEME_HTTP:
1439  case URL_SCHEME_HTTPS:
1440  case URL_SCHEME_MK:
1441  return TRUE;
1442  }
1443 
1444  return FALSE;
1445 }
1446 
1447 static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, IUri *uri, IBindCtx *pbc,
1448  BOOL to_obj, REFIID riid, Binding **binding)
1449 {
1450  Binding *ret;
1451  HRESULT hres;
1452 
1454 
1455  ret = heap_alloc_zero(sizeof(Binding));
1456 
1457  ret->IBinding_iface.lpVtbl = &BindingVtbl;
1458  ret->IInternetProtocolSink_iface.lpVtbl = &InternetProtocolSinkVtbl;
1459  ret->IInternetBindInfo_iface.lpVtbl = &InternetBindInfoVtbl;
1460  ret->IWinInetHttpInfo_iface.lpVtbl = &WinInetHttpInfoVtbl;
1461  ret->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
1462 
1463  ret->ref = 1;
1464 
1465  ret->to_object = to_obj;
1466  ret->iid = *riid;
1467  ret->notif_hwnd = get_notif_hwnd();
1468  ret->report_mime = !binding_ctx;
1469  ret->download_state = BEFORE_DOWNLOAD;
1470 
1471  if(to_obj) {
1472  IBindCtx_AddRef(pbc);
1473  ret->bctx = pbc;
1474  }
1475 
1476  if(mon) {
1477  IMoniker_AddRef(mon);
1478  ret->mon = mon;
1479  }
1480 
1481  ret->bindinfo.cbSize = sizeof(BINDINFO);
1482 
1483  InitializeCriticalSection(&ret->section);
1484  ret->section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": Binding.section");
1485 
1486  hres = get_callback(pbc, &ret->callback);
1487  if(FAILED(hres)) {
1488  WARN("Could not get IBindStatusCallback\n");
1489  IBinding_Release(&ret->IBinding_iface);
1490  return hres;
1491  }
1492 
1493  IBindStatusCallback_QueryInterface(ret->callback, &IID_IServiceProvider,
1494  (void**)&ret->service_provider);
1495 
1496  if(binding_ctx) {
1497  ret->protocol = binding_ctx->protocol;
1498  IInternetProtocolEx_AddRef(&ret->protocol->IInternetProtocolEx_iface);
1499  }else {
1500  hres = create_binding_protocol(&ret->protocol);
1501  if(FAILED(hres)) {
1502  WARN("Could not get protocol handler\n");
1503  IBinding_Release(&ret->IBinding_iface);
1504  return hres;
1505  }
1506  }
1507 
1508  hres = IBindStatusCallback_GetBindInfo(ret->callback, &ret->bindf, &ret->bindinfo);
1509  if(FAILED(hres)) {
1510  WARN("GetBindInfo failed: %08x\n", hres);
1511  IBinding_Release(&ret->IBinding_iface);
1512  return hres;
1513  }
1514 
1515  TRACE("bindf %08x\n", ret->bindf);
1516  dump_BINDINFO(&ret->bindinfo);
1517 
1518  ret->bindf |= BINDF_FROMURLMON;
1519  if(to_obj)
1520  ret->bindinfo.dwOptions |= 0x100000;
1521 
1522  if(!(ret->bindf & BINDF_ASYNCHRONOUS) || !(ret->bindf & BINDF_PULLDATA)) {
1523  ret->bindf |= BINDF_NEEDFILE;
1524  ret->use_cache_file = TRUE;
1525  }else if(!is_urlmon_protocol(uri)) {
1526  ret->bindf |= BINDF_NEEDFILE;
1527  }
1528 
1529  hres = IUri_GetDisplayUri(uri, &ret->url);
1530  if(FAILED(hres)) {
1531  IBinding_Release(&ret->IBinding_iface);
1532  return hres;
1533  }
1534 
1535  if(binding_ctx) {
1536  ret->stgmed_buf = binding_ctx->stgmed_buf;
1537  IUnknown_AddRef(&ret->stgmed_buf->IUnknown_iface);
1538  ret->clipboard_format = binding_ctx->clipboard_format;
1539  }else {
1540  ret->stgmed_buf = create_stgmed_buf(&ret->protocol->IInternetProtocolEx_iface);
1541  }
1542 
1543  if(to_obj) {
1544  ret->stgmed_obj = NULL;
1545  }else if(IsEqualGUID(&IID_IStream, riid)) {
1546  ret->stgmed_obj = create_stgmed_stream(ret->stgmed_buf);
1547  }else if(IsEqualGUID(&IID_IUnknown, riid)) {
1548  ret->bindf |= BINDF_NEEDFILE;
1549  ret->stgmed_obj = create_stgmed_file(ret->stgmed_buf);
1550  }else {
1551  FIXME("Unsupported riid %s\n", debugstr_guid(riid));
1552  IBinding_Release(&ret->IBinding_iface);
1553  return E_NOTIMPL;
1554  }
1555 
1556  *binding = ret;
1557  return S_OK;
1558 }
1559 
1560 static HRESULT start_binding(IMoniker *mon, Binding *binding_ctx, IUri *uri, IBindCtx *pbc,
1561  BOOL to_obj, REFIID riid, Binding **ret)
1562 {
1563  Binding *binding = NULL;
1564  HRESULT hres;
1565  MSG msg;
1566 
1567  hres = Binding_Create(mon, binding_ctx, uri, pbc, to_obj, riid, &binding);
1568  if(FAILED(hres))
1569  return hres;
1570 
1571  hres = IBindStatusCallback_OnStartBinding(binding->callback, 0, &binding->IBinding_iface);
1572  if(FAILED(hres)) {
1573  WARN("OnStartBinding failed: %08x\n", hres);
1574  if(hres != E_ABORT && hres != E_NOTIMPL)
1575  hres = INET_E_DOWNLOAD_FAILURE;
1576 
1577  stop_binding(binding, hres, NULL);
1578  IBinding_Release(&binding->IBinding_iface);
1579  return hres;
1580  }
1581 
1582  if(binding_ctx) {
1584  &binding->IInternetBindInfo_iface);
1585  if(binding_ctx->redirect_url)
1586  IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_REDIRECTING, binding_ctx->redirect_url);
1587  report_data(binding, BSCF_FIRSTDATANOTIFICATION | (binding_ctx->download_state == END_DOWNLOAD ? BSCF_LASTDATANOTIFICATION : 0),
1588  0, 0);
1589  }else {
1590  hres = IInternetProtocolEx_StartEx(&binding->protocol->IInternetProtocolEx_iface, uri,
1592  PI_APARTMENTTHREADED|PI_MIMEVERIFICATION, 0);
1593 
1594  TRACE("start ret %08x\n", hres);
1595 
1596  if(FAILED(hres) && hres != E_PENDING) {
1597  stop_binding(binding, hres, NULL);
1598  IBinding_Release(&binding->IBinding_iface);
1599 
1600  return hres;
1601  }
1602  }
1603 
1604  while(!(binding->bindf & BINDF_ASYNCHRONOUS) &&
1605  !(binding->state & BINDING_STOPPED)) {
1607  while (PeekMessageW(&msg, binding->notif_hwnd, WM_USER, WM_USER+117, PM_REMOVE|PM_NOYIELD)) {
1610  }
1611  }
1612 
1613  *ret = binding;
1614  return S_OK;
1615 }
1616 
1618 {
1619  Binding *binding = NULL, *binding_ctx;
1620  HRESULT hres;
1621 
1622  binding_ctx = get_bctx_binding(pbc);
1623 
1624  hres = start_binding(NULL, binding_ctx, uri, pbc, FALSE, riid, &binding);
1625  if(binding_ctx)
1626  IBinding_Release(&binding_ctx->IBinding_iface);
1627  if(FAILED(hres))
1628  return hres;
1629 
1630  if(binding->hres == S_OK && binding->download_state != BEFORE_DOWNLOAD /* FIXME */) {
1631  if((binding->state & BINDING_STOPPED) && (binding->state & BINDING_LOCKED))
1632  IInternetProtocolEx_UnlockRequest(&binding->protocol->IInternetProtocolEx_iface);
1633 
1634  hres = binding->stgmed_obj->vtbl->get_result(binding->stgmed_obj, binding->bindf, ppv);
1635  }else if(binding->bindf & BINDF_ASYNCHRONOUS) {
1636  hres = MK_S_ASYNCHRONOUS;
1637  }else {
1638  hres = FAILED(binding->hres) ? binding->hres : S_OK;
1639  }
1640 
1641  IBinding_Release(&binding->IBinding_iface);
1642 
1643  return hres;
1644 }
1645 
1647 {
1648  Binding *binding;
1649  HRESULT hres;
1650 
1651  *ppv = NULL;
1652 
1653  hres = start_binding(mon, NULL, uri, pbc, TRUE, riid, &binding);
1654  if(FAILED(hres))
1655  return hres;
1656 
1657  if(binding->hres != S_OK) {
1658  hres = SUCCEEDED(binding->hres) ? S_OK : binding->hres;
1659  }else if(binding->bindf & BINDF_ASYNCHRONOUS) {
1660  hres = MK_S_ASYNCHRONOUS;
1661  }else {
1662  *ppv = binding->obj;
1663  IUnknown_AddRef(binding->obj);
1664  hres = S_OK;
1665  }
1666 
1667  IBinding_Release(&binding->IBinding_iface);
1668 
1669  return hres;
1670 }
static stgmed_buf_t * impl_from_IUnknown(IUnknown *iface)
Definition: binding.c:338
BOOL WINAPI SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
Definition: fileinfo.c:327
static stgmed_buf_t * create_stgmed_buf(IInternetProtocolEx *protocol)
Definition: binding.c:397
#define BINDING_STOPPED
Definition: binding.c:64
stgmed_buf_t * buf
Definition: binding.c:700
IServiceProvider IServiceProvider_iface
Definition: binding.c:73
#define HRESULT
Definition: msvc.h:9
download_state_t
Definition: binding.c:57
static void stgmed_file_release(stgmed_obj_t *obj)
Definition: binding.c:719
static WCHAR cbinding_contextW[]
Definition: binding.c:29
BOOL WINAPI TranslateMessage(_In_ const MSG *)
static HRESULT get_callback(IBindCtx *pbc, IBindStatusCallback **callback)
Definition: binding.c:1411
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
static const stgmed_obj_vtbl stgmed_file_vtbl
Definition: binding.c:750
#define E_NOINTERFACE
Definition: winerror.h:2364
static HRESULT WINAPI Binding_Suspend(IBinding *iface)
Definition: binding.c:901
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define ERROR_SUCCESS
Definition: deptool.c:10
static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
Definition: binding.c:1175
#define DWORD_PTR
Definition: treelist.c:76
Definition: scsiwmi.h:51
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
const WCHAR * mime
Definition: mimefilter.c:512
static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
Definition: binding.c:1164
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
HRESULT create_binding_protocol(BindProtocol **protocol)
Definition: bindprot.c:1435
HWND notif_hwnd
Definition: binding.c:102
const char * uri
Definition: sec_mgr.c:1594
REFIID riid
Definition: precomp.h:44
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
void WINAPI ReleaseBindInfo(BINDINFO *pbindinfo)
Definition: urlmon_main.c:572
static HRESULT WINAPI WinInetHttpInfo_QueryInterface(IWinInetHttpInfo *iface, REFIID riid, void **ppv)
Definition: binding.c:1297
IInternetBindInfo IInternetBindInfo_iface
Definition: binding.c:71
IInternetProtocolEx * protocol
Definition: binding.c:37
static HRESULT WINAPI InternetProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv)
Definition: binding.c:989
#define FILE_CURRENT
Definition: winbase.h:113
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
static ULONG WINAPI ProtocolStream_Release(IStream *iface)
Definition: binding.c:466
static Binding * impl_from_IWinInetHttpInfo(IWinInetHttpInfo *iface)
Definition: binding.c:1292
IUnknown * obj
Definition: binding.c:99
#define WARN(fmt,...)
Definition: debug.h:111
REFIID LPVOID * ppv
Definition: atlbase.h:39
static ULONG WINAPI StgMedUnk_AddRef(IUnknown *iface)
Definition: binding.c:361
static ULONG WINAPI StgMedUnk_Release(IUnknown *iface)
Definition: binding.c:371
LPWSTR redirect_url
Definition: binding.c:91
static ULONG WINAPI Binding_Release(IBinding *iface)
Definition: binding.c:841
static void stop_binding(Binding *binding, HRESULT hres, LPCWSTR str)
Definition: binding.c:174
DWORD scheme
static void stgmed_stream_release(stgmed_obj_t *obj)
Definition: binding.c:662
static HRESULT WINAPI StgMedUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: binding.c:343
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
DWORD state
Definition: binding.c:95
static HRESULT WINAPI ProtocolStream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
Definition: binding.c:519
static HRESULT WINAPI ProtocolStream_QueryInterface(IStream *iface, REFIID riid, void **ppv)
Definition: binding.c:429
#define STG_E_INSUFFICIENTMEMORY
Definition: winerror.h:2570
static ULONG WINAPI InternetBindInfo_Release(IInternetBindInfo *iface)
Definition: binding.c:1216
HRESULT hres
Definition: binding.c:96
static HRESULT stgmed_stream_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed)
Definition: binding.c:668
HRESULT(* get_result)(stgmed_obj_t *, DWORD, void **)
Definition: binding.c:50
static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl
Definition: binding.c:1188
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
static LPOLESTR
Definition: stg_prop.c:27
static LPWSTR get_mime_clsid(LPCWSTR mime, CLSID *clsid)
Definition: binding.c:189
#define lstrlenW
Definition: compat.h:407
#define E_FAIL
Definition: ddrawi.h:102
#define BINDING_ABORTED
Definition: binding.c:66
static void load_doc_mon(Binding *binding, IPersistMoniker *persist)
Definition: binding.c:234
static WCHAR bscb_holderW[]
Definition: binding.c:30
#define DWORD
Definition: nt_native.h:44
Definition: send.c:47
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define FILE_SHARE_READ
Definition: compat.h:125
static ULONG WINAPI InternetProtocolSink_AddRef(IInternetProtocolSink *iface)
Definition: binding.c:996
static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
Definition: binding.c:1366
#define BINDING_LOCKED
Definition: binding.c:63
static HRESULT WINAPI ProtocolStream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
Definition: binding.c:559
static HRESULT WINAPI Binding_GetPriority(IBinding *iface, LONG *pnPriority)
Definition: binding.c:922
static HRESULT WINAPI ProtocolStream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
Definition: binding.c:483
const stgmed_obj_vtbl * vtbl
Definition: binding.c:54
static const stgmed_obj_vtbl stgmed_stream_vtbl
Definition: binding.c:692
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
static const IBindingVtbl BindingVtbl
Definition: binding.c:952
static HRESULT stgmed_file_get_result(stgmed_obj_t *obj, DWORD bindf, void **result)
Definition: binding.c:745
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
static Binding * impl_from_IBinding(IBinding *iface)
Definition: binding.c:768
#define STG_E_ACCESSDENIED
Definition: winerror.h:2568
HRESULT bind_to_object(IMoniker *mon, IUri *uri, IBindCtx *pbc, REFIID riid, void **ppv)
Definition: binding.c:1646
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
UINT clipboard_format
Definition: binding.c:89
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: propsheet.c:178
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3311
LONG ref
Definition: binding.c:75
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode, LPCWSTR szStatusText)
Definition: binding.c:1025
IBinding IBinding_iface
Definition: binding.c:69
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
Definition: binding.c:1373
const WCHAR * str
static stgmed_obj_t * create_stgmed_file(stgmed_buf_t *buf)
Definition: binding.c:756
HANDLE file
Definition: binding.c:39
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:697
smooth NULL
Definition: ftsmooth.c:416
PVOID pBuffer
static HRESULT WINAPI ProtocolStream_CopyTo(IStream *iface, IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
Definition: binding.c:566
static ULONG WINAPI Binding_AddRef(IBinding *iface)
Definition: binding.c:831
CLSID clsid
Definition: binding.c:97
static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progress_max)
Definition: binding.c:1078
HRESULT create_default_callback(IBindStatusCallback **ret)
Definition: download.c:361
static Binding * impl_from_IInternetBindInfo(IInternetBindInfo *iface)
Definition: binding.c:1198
#define debugstr_guid
Definition: kernel32.h:35
static const IUnknownVtbl StgMedUnkVtbl
Definition: binding.c:391
static HRESULT WINAPI ProtocolStream_Commit(IStream *iface, DWORD grfCommitFlags)
Definition: binding.c:574
#define OPEN_EXISTING
Definition: compat.h:426
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
stgmed_obj_t stgmed_obj
Definition: binding.c:416
static void URLMON_UnlockModule(void)
Definition: urlmon_main.h:68
LPWSTR mime
Definition: binding.c:88
struct _ULARGE_INTEGER::@3737 u
download_state_t download_state
Definition: binding.c:98
HRESULT WINAPI CopyBindInfo(const BINDINFO *pcbiSrc, BINDINFO *pcbiDest)
Definition: urlmon_main.c:654
MmuTrapHandler callback[0x30]
Definition: mmuobject.c:44
static const IInternetBindInfoVtbl InternetBindInfoVtbl
Definition: binding.c:1284
IWinInetHttpInfo IWinInetHttpInfo_iface
Definition: binding.c:72
#define TRACE(s)
Definition: solgame.cpp:4
void release_notif_hwnd(HWND hwnd)
Definition: bindprot.c:141
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
static const WCHAR clsidW[]
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
#define FILE_END
Definition: winbase.h:114
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define CLSID_NULL
Definition: guiddef.h:94
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
LONG HRESULT
Definition: typedefs.h:77
static Binding * impl_from_IServiceProvider(IServiceProvider *iface)
Definition: binding.c:1361
const GUID IID_IUnknown
const char * debugstr_bindstatus(ULONG status)
Definition: urlmon_main.c:175
BindProtocol * protocol
Definition: binding.c:80
#define WINAPI
Definition: msvc.h:8
HWND get_notif_hwnd(void)
Definition: bindprot.c:111
static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData)
Definition: binding.c:1008
unsigned long DWORD
Definition: ntddk_ex.h:95
static ULONG WINAPI WinInetHttpInfo_AddRef(IWinInetHttpInfo *iface)
Definition: binding.c:1303
static void dump_BINDINFO(BINDINFO *bi)
Definition: binding.c:117
HRESULT bind_to_storage(IUri *uri, IBindCtx *pbc, REFIID riid, void **ppv)
Definition: binding.c:1617
stgmed_buf_t * buf
Definition: binding.c:421
static HRESULT WINAPI WinInetHttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD dwOption, void *pBuffer, DWORD *pcbBuffer)
Definition: binding.c:1315
static DWORD cb
Definition: integrity.c:41
method
Definition: dragdrop.c:53
LPWSTR cache_file
Definition: binding.c:42
static ULONG WINAPI InternetBindInfo_AddRef(IInternetBindInfo *iface)
Definition: binding.c:1210
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
static HRESULT WINAPI ProtocolStream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: binding.c:592
#define GetFileSizeEx
Definition: compat.h:414
static HRESULT WINAPI Binding_SetPriority(IBinding *iface, LONG nPriority)
Definition: binding.c:915
IInternetProtocolSink IInternetProtocolSink_iface
Definition: binding.c:70
static HRESULT stgmed_file_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed)
Definition: binding.c:727
int ret
stgmed_buf_t * stgmed_buf
Definition: binding.c:82
BOOL report_mime
Definition: binding.c:93
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
REFCLSID clsid
Definition: msctf.c:84
static HRESULT WINAPI Binding_QueryInterface(IBinding *iface, REFIID riid, void **ppv)
Definition: binding.c:773
IInternetProtocolEx IInternetProtocolEx_iface
Definition: urlmon_main.h:174
static HRESULT WINAPI WinInetHttpInfo_QueryInfo(IWinInetHttpInfo *iface, DWORD dwOption, void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved)
Definition: binding.c:1334
#define InterlockedDecrement
Definition: armddk.h:52
Definition: parse.h:22
static HRESULT WINAPI ProtocolStream_Revert(IStream *iface)
Definition: binding.c:583
static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
Definition: binding.c:1379
static const IServiceProviderVtbl ServiceProviderVtbl
Definition: binding.c:1404
static HRESULT WINAPI Binding_Resume(IBinding *iface)
Definition: binding.c:908
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:199
static stgmed_obj_t * create_stgmed_stream(stgmed_buf_t *buf)
Definition: binding.c:703
#define GENERIC_READ
Definition: compat.h:124
BINDINFO bindinfo
Definition: binding.c:85
static void cache_file_available(Binding *This, const WCHAR *file_name)
Definition: binding.c:325
#define E_ABORT
Definition: winerror.h:2366
HRESULT WINAPI CreateAsyncBindCtxEx(IBindCtx *ibind, DWORD options, IBindStatusCallback *callback, IEnumFORMATETC *format, IBindCtx **pbind, DWORD reserved)
Definition: bindctx.c:929
#define WM_USER
Definition: winuser.h:1856
_Reserved_ DWORD * pdwReserved
Definition: wincrypt.h:4254
static ULONG WINAPI WinInetHttpInfo_Release(IWinInetHttpInfo *iface)
Definition: binding.c:1309
DWORD bindf
Definition: binding.c:86
static IBinding Binding
Definition: htmldoc.c:1268
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3234
IBindStatusCallback * callback
Definition: binding.c:77
LONG ref
Definition: binding.c:35
IUnknown IUnknown_iface
Definition: binding.c:33
static void on_progress(Binding *This, ULONG progress, ULONG progress_max, ULONG status_code, LPCWSTR status_text)
Definition: binding.c:1018
#define S_OK
Definition: intsafe.h:59
#define FILE_BEGIN
Definition: winbase.h:112
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:2696
static Binding * get_bctx_binding(IBindCtx *bctx)
Definition: binding.c:964
#define InterlockedIncrement
Definition: armddk.h:53
stgmed_obj_t stgmed_obj
Definition: binding.c:699
#define lstrcpyW
Definition: compat.h:406
_In_ UINT _In_ DWORD _Out_ DWORD * pdwResult
Definition: ntgdi.h:248
IMoniker * mon
Definition: binding.c:100
static HRESULT WINAPI ProtocolStream_Stat(IStream *iface, STATSTG *pstatstg, DWORD dwStatFlag)
Definition: binding.c:608
#define ARRAY_SIZE(a)
Definition: main.h:24
static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv)
Definition: binding.c:1385
static ULONG WINAPI ProtocolStream_AddRef(IStream *iface)
Definition: binding.c:456
#define PM_NOYIELD
Definition: winuser.h:1183
#define E_NOTIMPL
Definition: ddrawi.h:99
static void create_object(Binding *binding)
Definition: binding.c:293
#define QS_POSTMESSAGE
Definition: winuser.h:888
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:274
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
LPWSTR url
Definition: binding.c:90
IID iid
Definition: binding.c:92
WINE_DEFAULT_DEBUG_CHANNEL(urlmon)
IBindCtx * bctx
Definition: binding.c:101
cd_progress_ptr progress
Definition: cdjpeg.h:150
static ProtocolStream * impl_from_IStream(IStream *iface)
Definition: binding.c:424
static const IStreamVtbl ProtocolStreamVtbl
Definition: binding.c:645
static void mime_available(Binding *This, LPCWSTR mime)
Definition: binding.c:161
static HRESULT WINAPI InternetBindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
Definition: binding.c:1222
static HRESULT WINAPI ProtocolStream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
Definition: binding.c:509
static LPCWSTR file_name
Definition: protocol.c:146
#define CreateFileW
Definition: compat.h:400
IServiceProvider * service_provider
Definition: binding.c:78
static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, IUri *uri, IBindCtx *pbc, BOOL to_obj, REFIID riid, Binding **binding)
Definition: binding.c:1447
#define msg(x)
Definition: auth_time.c:54
IStream IStream_iface
Definition: request.c:4077
static HRESULT stgmed_stream_get_result(stgmed_obj_t *obj, DWORD bindf, void **result)
Definition: binding.c:679
struct _LARGE_INTEGER::@2192 u
GLuint res
Definition: glext.h:9613
#define BINDING_OBJAVAIL
Definition: binding.c:65
stgmed_obj_t * stgmed_obj
Definition: binding.c:83
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2247
unsigned int ULONG
Definition: retypes.h:1
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
static HRESULT WINAPI Binding_Abort(IBinding *iface)
Definition: binding.c:882
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define PM_REMOVE
Definition: winuser.h:1182
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static void URLMON_LockModule(void)
Definition: urlmon_main.h:67
static HRESULT WINAPI ProtocolStream_Clone(IStream *iface, IStream **ppstm)
Definition: binding.c:638
static void read_protocol_data(stgmed_buf_t *stgmed_buf)
Definition: binding.c:107
static HRESULT WINAPI InternetBindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
Definition: binding.c:1233
#define E_PENDING
Definition: dinput.h:172
CRITICAL_SECTION section
Definition: binding.c:104
static ULONG WINAPI InternetProtocolSink_Release(IInternetProtocolSink *iface)
Definition: binding.c:1002
static Binding * impl_from_IInternetProtocolSink(IInternetProtocolSink *iface)
Definition: binding.c:984
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
IStream IStream_iface
Definition: binding.c:417
void set_binding_sink(BindProtocol *This, IInternetProtocolSink *sink, IInternetBindInfo *bind_info)
Definition: bindprot.c:560
BOOL to_object
Definition: binding.c:87
BYTE * PBYTE
Definition: pedump.c:66
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
static HRESULT WINAPI Binding_GetBindResult(IBinding *iface, CLSID *pclsidProtocol, DWORD *pdwResult, LPOLESTR *pszResult, DWORD *pdwReserved)
Definition: binding.c:929
BOOL WINAPI GetFileTime(IN HANDLE hFile, OUT LPFILETIME lpCreationTime OPTIONAL, OUT LPFILETIME lpLastAccessTime OPTIONAL, OUT LPFILETIME lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:1046
static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl
Definition: binding.c:1353
static HRESULT WINAPI ProtocolStream_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: binding.c:600
HRESULT hres
Definition: binding.c:40
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static HRESULT WINAPI InternetBindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv)
Definition: binding.c:1203
static HRESULT start_binding(IMoniker *mon, Binding *binding_ctx, IUri *uri, IBindCtx *pbc, BOOL to_obj, REFIID riid, Binding **ret)
Definition: binding.c:1560
LONGLONG QuadPart
Definition: typedefs.h:112
static HRESULT create_mime_object(Binding *binding, const CLSID *clsid, LPCWSTR clsid_str)
Definition: binding.c:255
BOOL use_cache_file
Definition: binding.c:94
static BOOL is_urlmon_protocol(IUri *uri)
Definition: binding.c:1425
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
static DWORD bindf
Definition: protocol.c:70