static HRESULT WINAPI DwlServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv) { DownloadBSC *This = SERVPROV_THIS(iface); IServiceProvider *serv_prov; HRESULT hres; TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv); if(!This->callback) return E_NOINTERFACE; hres = IBindStatusCallback_QueryInterface(This->callback, riid, ppv); if(SUCCEEDED(hres)) return S_OK; hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IServiceProvider, (void**)&serv_prov); if(SUCCEEDED(hres)) { hres = IServiceProvider_QueryService(serv_prov, guidService, riid, ppv); IServiceProvider_Release(serv_prov); return hres; } return E_NOINTERFACE; }
static HRESULT WINAPI BSCServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv) { BindStatusCallback *This = SERVPROV_THIS(iface); HRESULT hres; if(IsEqualGUID(&IID_IHttpNegotiate, guidService)) { TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This, debugstr_guid(riid), ppv); return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); } if(IsEqualGUID(&IID_IHttpNegotiate2, guidService)) { TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This, debugstr_guid(riid), ppv); return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); } if(IsEqualGUID(&IID_IAuthenticate, guidService)) { TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This, debugstr_guid(riid), ppv); return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); } TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv); hres = IBindStatusCallback_QueryInterface(This->callback, riid, ppv); if(SUCCEEDED(hres)) return S_OK; if(This->serv_prov) { hres = IServiceProvider_QueryService(This->serv_prov, guidService, riid, ppv); if(SUCCEEDED(hres)) return S_OK; } return E_NOINTERFACE; }
static void *get_callback_iface(BindStatusCallback *This, REFIID riid) { void *ret; HRESULT hres; hres = IBindStatusCallback_QueryInterface(This->callback, riid, (void**)&ret); if(FAILED(hres) && This->serv_prov) hres = IServiceProvider_QueryService(This->serv_prov, riid, riid, &ret); return SUCCEEDED(hres) ? ret : NULL; }
/*********************************************************************** * RegisterBindStatusCallback (urlmon.@) * * Register a bind status callback. * * PARAMS * pbc [I] Binding context * pbsc [I] Callback to register * ppbscPrevious [O] Destination for previous callback * dwReserved [I] Reserved, must be 0. * * RETURNS * Success: S_OK. * Failure: E_INVALIDARG, if any argument is invalid, or * E_OUTOFMEMORY if memory allocation fails. */ HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc, IBindStatusCallback **ppbscPrevious, DWORD dwReserved) { BindStatusCallback *holder; IBindStatusCallback *bsc, *prev = NULL; IUnknown *unk; HRESULT hres; TRACE("(%p %p %p %x)\n", pbc, pbsc, ppbscPrevious, dwReserved); if (!pbc || !pbsc) return E_INVALIDARG; hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk); if(SUCCEEDED(hres)) { hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&bsc); IUnknown_Release(unk); if(SUCCEEDED(hres)) { hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder); if(SUCCEEDED(hres)) { if(ppbscPrevious) { IBindStatusCallback_AddRef(holder->callback); *ppbscPrevious = holder->callback; } set_callback(holder, pbsc); IBindStatusCallback_Release(bsc); IBindStatusCallback_Release(STATUSCLB(holder)); return S_OK; }else { prev = bsc; } } IBindCtx_RevokeObjectParam(pbc, BSCBHolder); } hres = wrap_callback(pbsc, &bsc); if(SUCCEEDED(hres)) { hres = IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown*)bsc); IBindStatusCallback_Release(bsc); } if(FAILED(hres)) { if(prev) IBindStatusCallback_Release(prev); return hres; } if(ppbscPrevious) *ppbscPrevious = prev; return S_OK; }
static HRESULT navigate_hlink(DocHost *This, IMoniker *mon, IBindCtx *bindctx, IBindStatusCallback *callback) { IHttpNegotiate *http_negotiate; BindStatusCallback *bsc; PBYTE post_data = NULL; ULONG post_data_len = 0; LPWSTR headers = NULL, url; BINDINFO bindinfo; DWORD bindf = 0; HRESULT hres; TRACE("\n"); hres = IMoniker_GetDisplayName(mon, 0, NULL, &url); if(FAILED(hres)) FIXME("GetDisplayName failed: %08x\n", hres); hres = IBindStatusCallback_QueryInterface(callback, &IID_IHttpNegotiate, (void**)&http_negotiate); if(SUCCEEDED(hres)) { static const WCHAR null_string[] = {0}; IHttpNegotiate_BeginningTransaction(http_negotiate, null_string, null_string, 0, &headers); IHttpNegotiate_Release(http_negotiate); } memset(&bindinfo, 0, sizeof(bindinfo)); bindinfo.cbSize = sizeof(bindinfo); hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo); dump_BINDINFO(&bindinfo); if(bindinfo.dwBindVerb == BINDVERB_POST) { post_data_len = bindinfo.cbstgmedData; if(post_data_len) post_data = bindinfo.stgmedData.u.hGlobal; } if(This->doc_navigate) { hres = async_doc_navigate(This, url, headers, post_data, post_data_len, FALSE); }else { bsc = create_callback(This, url, post_data, post_data_len, headers); hres = navigate_bsc(This, bsc, mon); IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface); } CoTaskMemFree(url); CoTaskMemFree(headers); ReleaseBindInfo(&bindinfo); return hres; }
static HRESULT WINAPI InternetBindInfo_GetBindString(IInternetBindInfo *iface, ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched) { Binding *This = BINDINF_THIS(iface); TRACE("(%p)->(%d %p %d %p)\n", This, ulStringType, ppwzStr, cEl, pcElFetched); switch(ulStringType) { case BINDSTRING_ACCEPT_MIMES: { static const WCHAR wszMimes[] = {'*','/','*',0}; if(!ppwzStr || !pcElFetched) return E_INVALIDARG; ppwzStr[0] = CoTaskMemAlloc(sizeof(wszMimes)); memcpy(ppwzStr[0], wszMimes, sizeof(wszMimes)); *pcElFetched = 1; return S_OK; } case BINDSTRING_USER_AGENT: { IInternetBindInfo *bindinfo = NULL; HRESULT hres; hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IInternetBindInfo, (void**)&bindinfo); if(FAILED(hres)) return hres; hres = IInternetBindInfo_GetBindString(bindinfo, ulStringType, ppwzStr, cEl, pcElFetched); IInternetBindInfo_Release(bindinfo); return hres; } case BINDSTRING_URL: { DWORD size = (SysStringLen(This->url)+1) * sizeof(WCHAR); if(!ppwzStr || !pcElFetched) return E_INVALIDARG; *ppwzStr = CoTaskMemAlloc(size); memcpy(*ppwzStr, This->url, size); *pcElFetched = 1; return S_OK; } } FIXME("not supported string type %d\n", ulStringType); return E_NOTIMPL; }
/*********************************************************************** * RegisterBindStatusCallback (urlmon.@) * * Register a bind status callback. * * PARAMS * pbc [I] Binding context * pbsc [I] Callback to register * ppbscPrevious [O] Destination for previous callback * dwReserved [I] Reserved, must be 0. * * RETURNS * Success: S_OK. * Failure: E_INVALIDARG, if any argument is invalid, or * E_OUTOFMEMORY if memory allocation fails. */ HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc, IBindStatusCallback **ppbscPrevious, DWORD dwReserved) { BindStatusCallback *holder; IBindStatusCallback *bsc, *prev = NULL; HRESULT hres; TRACE("(%p %p %p %x)\n", pbc, pbsc, ppbscPrevious, dwReserved); if (!pbc || !pbsc) return E_INVALIDARG; bsc = bsch_from_bctx(pbc); if(bsc) { hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder); if(SUCCEEDED(hres)) { if(ppbscPrevious) { IBindStatusCallback_AddRef(holder->callback); *ppbscPrevious = holder->callback; } set_callback(holder, pbsc); IBindStatusCallback_Release(bsc); IBindStatusCallbackEx_Release(&holder->IBindStatusCallbackEx_iface); return S_OK; }else { prev = bsc; } IBindCtx_RevokeObjectParam(pbc, bscb_holderW); } hres = wrap_callback(pbsc, &bsc); if(SUCCEEDED(hres)) { hres = IBindCtx_RegisterObjectParam(pbc, bscb_holderW, (IUnknown*)bsc); IBindStatusCallback_Release(bsc); } if(FAILED(hres)) { if(prev) IBindStatusCallback_Release(prev); return hres; } if(ppbscPrevious) *ppbscPrevious = prev; return S_OK; }
static void set_callback(BindStatusCallback *This, IBindStatusCallback *bsc) { IServiceProvider *serv_prov; HRESULT hres; if(This->callback) IBindStatusCallback_Release(This->callback); if(This->serv_prov) IServiceProvider_Release(This->serv_prov); IBindStatusCallback_AddRef(bsc); This->callback = bsc; hres = IBindStatusCallback_QueryInterface(bsc, &IID_IServiceProvider, (void**)&serv_prov); This->serv_prov = hres == S_OK ? serv_prov : NULL; }
static IBindStatusCallback *create_bsc(IBindStatusCallback *bsc) { BindStatusCallback *ret = heap_alloc_zero(sizeof(BindStatusCallback)); ret->lpBindStatusCallbackVtbl = &BindStatusCallbackVtbl; ret->lpServiceProviderVtbl = &BSCServiceProviderVtbl; ret->lpHttpNegotiate2Vtbl = &BSCHttpNegotiateVtbl; ret->lpAuthenticateVtbl = &BSCAuthenticateVtbl; ret->ref = 1; IBindStatusCallback_AddRef(bsc); ret->callback = bsc; IBindStatusCallback_QueryInterface(bsc, &IID_IServiceProvider, (void**)&ret->serv_prov); return STATUSCLB(ret); }
static HRESULT WINAPI BindStatusCallback_GetBindInfoEx(IBindStatusCallbackEx *iface, DWORD *grfBINDF, BINDINFO *pbindinfo, DWORD *grfBINDF2, DWORD *pdwReserved) { BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface); IBindStatusCallbackEx *bscex; HRESULT hres; TRACE("(%p)->(%p %p %p %p)\n", This, grfBINDF, pbindinfo, grfBINDF2, pdwReserved); hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IBindStatusCallbackEx, (void**)&bscex); if(SUCCEEDED(hres)) { hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, grfBINDF, pbindinfo, grfBINDF2, pdwReserved); IBindStatusCallbackEx_Release(bscex); }else { hres = IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo); } return hres; }
static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallbackEx *iface, DWORD *grfBINDF, BINDINFO *pbindinfo) { BindStatusCallback *This = STATUSCLB_THIS(iface); IBindStatusCallbackEx *bscex; HRESULT hres; TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo); hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IBindStatusCallbackEx, (void**)&bscex); if(SUCCEEDED(hres)) { DWORD bindf2 = 0, reserv = 0; hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, grfBINDF, pbindinfo, &bindf2, &reserv); IBindStatusCallbackEx_Release(bscex); }else { hres = IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo); } return hres; }
static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *bind_flags, BINDINFO *pbindinfo) { BindStatusCallback *This = impl_from_IBindStatusCallback(iface); TRACE("(%p)->(%p %p)\n", This, bind_flags, pbindinfo); *bind_flags = 0; if (This->request->async) *bind_flags |= BINDF_ASYNCHRONOUS; if (This->request->verb != BINDVERB_GET && This->body) { pbindinfo->stgmedData.tymed = TYMED_HGLOBAL; pbindinfo->stgmedData.u.hGlobal = This->body; pbindinfo->cbstgmedData = GlobalSize(This->body); /* callback owns passed body pointer */ IBindStatusCallback_QueryInterface(iface, &IID_IUnknown, (void**)&pbindinfo->stgmedData.pUnkForRelease); } pbindinfo->dwBindVerb = This->request->verb; return S_OK; }
IBindStatusCallback *bsc_from_bctx(IBindCtx *bctx) { BindStatusCallback *holder; IBindStatusCallback *bsc; HRESULT hres; bsc = bsch_from_bctx(bctx); if(!bsc) return NULL; hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder); if(FAILED(hres)) return bsc; if(holder->callback) { IBindStatusCallback_Release(bsc); bsc = holder->callback; IBindStatusCallback_AddRef(bsc); } IBindStatusCallbackEx_Release(&holder->IBindStatusCallbackEx_iface); return bsc; }
/*********************************************************************** * RevokeBindStatusCallback (URLMON.@) * * Unregister a bind status callback. * * pbc [I] Binding context * pbsc [I] Callback to unregister * * RETURNS * Success: S_OK. * Failure: E_INVALIDARG, if any argument is invalid */ HRESULT WINAPI RevokeBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc) { BindStatusCallback *holder; IBindStatusCallback *callback; IUnknown *unk; BOOL dorevoke = FALSE; HRESULT hres; TRACE("(%p %p)\n", pbc, pbsc); if (!pbc || !pbsc) return E_INVALIDARG; hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk); if(FAILED(hres)) return S_OK; hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&callback); IUnknown_Release(unk); if(FAILED(hres)) return S_OK; hres = IBindStatusCallback_QueryInterface(callback, &IID_IBindStatusCallbackHolder, (void**)&holder); if(SUCCEEDED(hres)) { if(pbsc == holder->callback) dorevoke = TRUE; IBindStatusCallback_Release(STATUSCLB(holder)); }else if(pbsc == callback) { dorevoke = TRUE; } IBindStatusCallback_Release(callback); if(dorevoke) IBindCtx_RevokeObjectParam(pbc, BSCBHolder); return S_OK; }
static BOOL install_warning(install_ctx_t *ctx) { IWindowForBindingUI *window_iface; HWND parent_hwnd = NULL; HRESULT hres; if(!ctx->callback) { FIXME("no callback\n"); return FALSE; } hres = IBindStatusCallback_QueryInterface(ctx->callback, &IID_IWindowForBindingUI, (void**)&window_iface); if(FAILED(hres)) return FALSE; hres = IWindowForBindingUI_GetWindow(window_iface, &IID_ICodeInstall, &ctx->hwnd); IWindowForBindingUI_Release(window_iface); if(FAILED(hres)) return FALSE; ctx->cancel = TRUE; DialogBoxParamW(urlmon_instance, MAKEINTRESOURCEW(ID_AXINSTALL_WARNING_DLG), parent_hwnd, warning_proc, (LPARAM)ctx); return !ctx->cancel; }
static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate *iface, REFIID riid, void **ppv) { BindStatusCallback *This = impl_from_IHttpNegotiate(iface); return IBindStatusCallback_QueryInterface(&This->IBindStatusCallback_iface, riid, ppv); }
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; }
static HRESULT WINAPI BSCHttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, REFIID riid, void **ppv) { BindStatusCallback *This = HTTPNEG2_THIS(iface); return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); }
static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate *iface, REFIID riid, void **ppv) { BindStatusCallback *This = HTTPNEG_THIS(iface); return IBindStatusCallback_QueryInterface(BINDSC(This), riid, ppv); }
static HRESULT WINAPI InstallCallbackBindInfo_QueryInterface(IInternetBindInfo *iface, REFIID riid, void **ppv) { return IBindStatusCallback_QueryInterface(&InstallCallback, riid, ppv); }
static HRESULT WINAPI BSCAuthenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv) { BindStatusCallback *This = AUTHENTICATE_THIS(iface); return IBindStatusCallback_QueryInterface(AUTHENTICATE(This), riid, ppv); }
static HRESULT WINAPI DwlServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv) { DownloadBSC *This = SERVPROV_THIS(iface); return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); }
static HRESULT WINAPI DwlServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv) { DownloadBSC *This = impl_from_IServiceProvider(iface); return IBindStatusCallback_QueryInterface(&This->IBindStatusCallback_iface, riid, ppv); }