static void stgmed_file_release(stgmed_obj_t *obj) { stgmed_file_obj_t *file_obj = (stgmed_file_obj_t*)obj; IUnknown_Release(STGMEDUNK(file_obj->buf)); heap_free(file_obj); }
static HRESULT WINAPI StgMedUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { stgmed_buf_t *This = STGMEDUNK_THIS(iface); *ppv = NULL; if(IsEqualGUID(riid, &IID_IUnknown)) { TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); *ppv = STGMEDUNK(This); IUnknown_AddRef(STGMEDUNK(This)); return S_OK; } TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); return E_NOINTERFACE; }
static HRESULT stgmed_stream_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed) { ProtocolStream *stream = (ProtocolStream*)obj; stgmed->tymed = TYMED_ISTREAM; stgmed->u.pstm = STREAM(stream); stgmed->pUnkForRelease = STGMEDUNK(stream->buf); return S_OK; }
static stgmed_obj_t *create_stgmed_file(stgmed_buf_t *buf) { stgmed_file_obj_t *ret = heap_alloc(sizeof(*ret)); ret->stgmed_obj.vtbl = &stgmed_file_vtbl; IUnknown_AddRef(STGMEDUNK(buf)); ret->buf = buf; return &ret->stgmed_obj; }
static stgmed_obj_t *create_stgmed_stream(stgmed_buf_t *buf) { ProtocolStream *ret = heap_alloc(sizeof(ProtocolStream)); ret->stgmed_obj.vtbl = &stgmed_stream_vtbl; ret->lpStreamVtbl = &ProtocolStreamVtbl; ret->ref = 1; IUnknown_AddRef(STGMEDUNK(buf)); ret->buf = buf; URLMON_LockModule(); return &ret->stgmed_obj; }
static ULONG WINAPI ProtocolStream_Release(IStream *iface) { ProtocolStream *This = STREAM_THIS(iface); LONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); if(!ref) { IUnknown_Release(STGMEDUNK(This->buf)); heap_free(This); URLMON_UnlockModule(); } return ref; }
static HRESULT stgmed_file_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed) { stgmed_file_obj_t *file_obj = (stgmed_file_obj_t*)obj; if(!file_obj->buf->cache_file) { WARN("cache_file not set\n"); return INET_E_DATA_NOT_AVAILABLE; } read_protocol_data(file_obj->buf); stgmed->tymed = TYMED_FILE; stgmed->u.lpszFileName = file_obj->buf->cache_file; stgmed->pUnkForRelease = STGMEDUNK(file_obj->buf); return S_OK; }
static ULONG WINAPI Binding_Release(IBinding *iface) { Binding *This = BINDING_THIS(iface); LONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); if(!ref) { if(This->notif_hwnd) release_notif_hwnd(This->notif_hwnd); if(This->mon) IMoniker_Release(This->mon); if(This->callback) IBindStatusCallback_Release(This->callback); if(This->protocol) IInternetProtocol_Release(This->protocol); if(This->service_provider) IServiceProvider_Release(This->service_provider); if(This->stgmed_buf) IUnknown_Release(STGMEDUNK(This->stgmed_buf)); if(This->stgmed_obj) This->stgmed_obj->vtbl->release(This->stgmed_obj); if(This->obj) IUnknown_Release(This->obj); if(This->bctx) IBindCtx_Release(This->bctx); ReleaseBindInfo(&This->bindinfo); This->section.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->section); heap_free(This->mime); heap_free(This->redirect_url); heap_free(This->url); heap_free(This); URLMON_UnlockModule(); } return ref; }
static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, IUri *uri, IBindCtx *pbc, BOOL to_obj, REFIID riid, Binding **binding) { Binding *ret; HRESULT hres; URLMON_LockModule(); ret = heap_alloc_zero(sizeof(Binding)); ret->lpBindingVtbl = &BindingVtbl; ret->lpIInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl; ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl; ret->lpWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl; ret->lpServiceProviderVtbl = &ServiceProviderVtbl; ret->ref = 1; ret->to_object = to_obj; ret->iid = *riid; ret->notif_hwnd = get_notif_hwnd(); ret->report_mime = !binding_ctx; ret->download_state = BEFORE_DOWNLOAD; if(to_obj) { IBindCtx_AddRef(pbc); ret->bctx = pbc; } if(mon) { IMoniker_AddRef(mon); ret->mon = mon; } ret->bindinfo.cbSize = sizeof(BINDINFO); InitializeCriticalSection(&ret->section); ret->section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": Binding.section"); hres = get_callback(pbc, &ret->callback); if(FAILED(hres)) { WARN("Could not get IBindStatusCallback\n"); IBinding_Release(BINDING(ret)); return hres; } IBindStatusCallback_QueryInterface(ret->callback, &IID_IServiceProvider, (void**)&ret->service_provider); if(binding_ctx) { ret->protocol = binding_ctx->protocol; IInternetProtocol_AddRef(ret->protocol); } else { hres = create_binding_protocol(TRUE, &ret->protocol); if(FAILED(hres)) { WARN("Could not get protocol handler\n"); IBinding_Release(BINDING(ret)); return hres; } } hres = IBindStatusCallback_GetBindInfo(ret->callback, &ret->bindf, &ret->bindinfo); if(FAILED(hres)) { WARN("GetBindInfo failed: %08x\n", hres); IBinding_Release(BINDING(ret)); return hres; } TRACE("bindf %08x\n", ret->bindf); dump_BINDINFO(&ret->bindinfo); ret->bindf |= BINDF_FROMURLMON; if(to_obj) ret->bindinfo.dwOptions |= 0x100000; if(!(ret->bindf & BINDF_ASYNCHRONOUS) || !(ret->bindf & BINDF_PULLDATA)) { ret->bindf |= BINDF_NEEDFILE; ret->use_cache_file = TRUE; } else if(!is_urlmon_protocol(uri)) { ret->bindf |= BINDF_NEEDFILE; } hres = IUri_GetDisplayUri(uri, &ret->url); if(FAILED(hres)) { IBinding_Release(BINDING(ret)); return hres; } if(binding_ctx) { ret->stgmed_buf = binding_ctx->stgmed_buf; IUnknown_AddRef(STGMEDUNK(ret->stgmed_buf)); ret->clipboard_format = binding_ctx->clipboard_format; } else { ret->stgmed_buf = create_stgmed_buf(ret->protocol); } if(to_obj) { ret->stgmed_obj = NULL; } else if(IsEqualGUID(&IID_IStream, riid)) { ret->stgmed_obj = create_stgmed_stream(ret->stgmed_buf); } else if(IsEqualGUID(&IID_IUnknown, riid)) { ret->bindf |= BINDF_NEEDFILE; ret->stgmed_obj = create_stgmed_file(ret->stgmed_buf); } else { FIXME("Unsupported riid %s\n", debugstr_guid(riid)); IBinding_Release(BINDING(ret)); return E_NOTIMPL; } *binding = ret; return S_OK; }