From 44606e911bdac5de7b9e3cca44996d3c88643601 Mon Sep 17 00:00:00 2001 From: The Wine Synchronizer Date: Thu, 29 Nov 2007 11:20:31 +0000 Subject: [PATCH] Autosyncing with Wine HEAD svn path=/trunk/; revision=30888 --- reactos/dll/win32/urlmon/bindctx.c | 854 +++++++++++++++++++++++++ reactos/dll/win32/urlmon/binding.c | 269 ++------ reactos/dll/win32/urlmon/bindprot.c | 4 +- reactos/dll/win32/urlmon/file.c | 16 +- reactos/dll/win32/urlmon/format.c | 12 +- reactos/dll/win32/urlmon/ftp.c | 6 +- reactos/dll/win32/urlmon/http.c | 116 ++-- reactos/dll/win32/urlmon/internet.c | 4 +- reactos/dll/win32/urlmon/mk.c | 18 +- reactos/dll/win32/urlmon/regsvr.c | 83 +-- reactos/dll/win32/urlmon/sec_mgr.c | 34 +- reactos/dll/win32/urlmon/session.c | 16 +- reactos/dll/win32/urlmon/umon.c | 271 ++------ reactos/dll/win32/urlmon/umstream.c | 334 +++++++++- reactos/dll/win32/urlmon/urlmon.rbuild | 10 +- reactos/dll/win32/urlmon/urlmon.spec | 10 +- reactos/dll/win32/urlmon/urlmon_main.c | 67 +- reactos/dll/win32/urlmon/urlmon_main.h | 23 +- 18 files changed, 1512 insertions(+), 635 deletions(-) create mode 100644 reactos/dll/win32/urlmon/bindctx.c diff --git a/reactos/dll/win32/urlmon/bindctx.c b/reactos/dll/win32/urlmon/bindctx.c new file mode 100644 index 00000000000..fb4136f0bdc --- /dev/null +++ b/reactos/dll/win32/urlmon/bindctx.c @@ -0,0 +1,854 @@ +/* + * Copyright 2007 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "winuser.h" +#include "ole2.h" +#include "urlmon.h" +#include "urlmon_main.h" + +#include "wine/debug.h" +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL(urlmon); + +static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 }; + +extern IID IID_IBindStatusCallbackHolder; + +typedef struct { + const IBindStatusCallbackVtbl *lpBindStatusCallbackVtbl; + const IServiceProviderVtbl *lpServiceProviderVtbl; + const IHttpNegotiate2Vtbl *lpHttpNegotiate2Vtbl; + const IAuthenticateVtbl *lpAuthenticateVtbl; + + LONG ref; + + IBindStatusCallback *callback; + IServiceProvider *serv_prov; + + IHttpNegotiate *http_negotiate; + BOOL init_http_negotiate; + IHttpNegotiate2 *http_negotiate2; + BOOL init_http_negotiate2; + IAuthenticate *authenticate; + BOOL init_authenticate; +} BindStatusCallback; + +#define STATUSCLB(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackVtbl) +#define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl) +#define HTTPNEG2(x) ((IHttpNegotiate2*) &(x)->lpHttpNegotiate2Vtbl) +#define AUTHENTICATE(x) ((IAuthenticate*) &(x)->lpAuthenticateVtbl) + +#define STATUSCLB_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallback, iface) + +static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface, + REFIID riid, void **ppv) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv); + *ppv = STATUSCLB(This); + }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) { + TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv); + *ppv = STATUSCLB(This); + }else if(IsEqualGUID(&IID_IBindStatusCallbackHolder, riid)) { + TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This, ppv); + *ppv = This; + }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { + TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv); + *ppv = SERVPROV(This); + }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) { + TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This, ppv); + *ppv = HTTPNEG2(This); + }else if(IsEqualGUID(&IID_IHttpNegotiate2, riid)) { + TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This, ppv); + *ppv = HTTPNEG2(This); + }else if(IsEqualGUID(&IID_IAuthenticate, riid)) { + TRACE("(%p)->(IID_IAuthenticate, %p)\n", This, ppv); + *ppv = AUTHENTICATE(This); + } + + if(*ppv) { + IBindStatusCallback_AddRef((IUnknown*)*ppv); + return S_OK; + } + + TRACE("Unsupported riid = %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref = %d\n", This, ref); + + return ref; +} + +static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref = %d\n", This, ref); + + if(!ref) { + if(This->serv_prov) + IServiceProvider_Release(This->serv_prov); + if(This->http_negotiate) + IHttpNegotiate_Release(This->http_negotiate); + if(This->http_negotiate2) + IHttpNegotiate2_Release(This->http_negotiate2); + if(This->authenticate) + IAuthenticate_Release(This->authenticate); + IBindStatusCallback_Release(This->callback); + urlmon_free(This); + } + + return ref; +} + +static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface, + DWORD dwReserved, IBinding *pbind) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind); + + return IBindStatusCallback_OnStartBinding(This->callback, 0xff, pbind); +} + +static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pnPriority); + + return IBindStatusCallback_GetPriority(This->callback, pnPriority); +} + +static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%d)\n", This, reserved); + + return IBindStatusCallback_OnLowResource(This->callback, reserved); +} + +static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress, + ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, + debugstr_w(szStatusText)); + + return IBindStatusCallback_OnProgress(This->callback, ulProgress, + ulProgressMax, ulStatusCode, szStatusText); +} + +static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, + HRESULT hresult, LPCWSTR szError) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError)); + + return IBindStatusCallback_OnStopBinding(This->callback, hresult, szError); +} + +static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, + DWORD *grfBINDF, BINDINFO *pbindinfo) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo); + + return IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo); +} + +static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, + DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed); + + return IBindStatusCallback_OnDataAvailable(This->callback, grfBSCF, dwSize, pformatetc, pstgmed); +} + +static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, + REFIID riid, IUnknown *punk) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk); + + return IBindStatusCallback_OnObjectAvailable(This->callback, riid, punk); +} + +#undef STATUSCLB_THIS + +static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = { + BindStatusCallback_QueryInterface, + BindStatusCallback_AddRef, + BindStatusCallback_Release, + BindStatusCallback_OnStartBinding, + BindStatusCallback_GetPriority, + BindStatusCallback_OnLowResource, + BindStatusCallback_OnProgress, + BindStatusCallback_OnStopBinding, + BindStatusCallback_GetBindInfo, + BindStatusCallback_OnDataAvailable, + BindStatusCallback_OnObjectAvailable +}; + +#define SERVPROV_THIS(iface) DEFINE_THIS(BindStatusCallback, ServiceProvider, iface) + +static HRESULT WINAPI BSCServiceProvider_QueryInterface(IServiceProvider *iface, + REFIID riid, void **ppv) +{ + BindStatusCallback *This = SERVPROV_THIS(iface); + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); +} + +static ULONG WINAPI BSCServiceProvider_AddRef(IServiceProvider *iface) +{ + BindStatusCallback *This = SERVPROV_THIS(iface); + return IBindStatusCallback_AddRef(STATUSCLB(This)); +} + +static ULONG WINAPI BSCServiceProvider_Release(IServiceProvider *iface) +{ + BindStatusCallback *This = SERVPROV_THIS(iface); + return IBindStatusCallback_Release(STATUSCLB(This)); +} + +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); + + if(!This->init_http_negotiate) { + This->init_http_negotiate = TRUE; + hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IHttpNegotiate, + (void**)&This->http_negotiate); + if(FAILED(hres) && This->serv_prov) + IServiceProvider_QueryService(This->serv_prov, &IID_IHttpNegotiate, + &IID_IHttpNegotiate, (void**)&This->http_negotiate); + } + + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); + } + + if(IsEqualGUID(&IID_IHttpNegotiate2, guidService)) { + TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This, debugstr_guid(riid), ppv); + + if(!This->init_http_negotiate2) { + This->init_http_negotiate2 = TRUE; + hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IHttpNegotiate2, + (void**)&This->http_negotiate2); + if(FAILED(hres) && This->serv_prov) + IServiceProvider_QueryService(This->serv_prov, &IID_IHttpNegotiate2, + &IID_IHttpNegotiate2, (void**)&This->http_negotiate2); + } + + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); + } + + if(IsEqualGUID(&IID_IAuthenticate, guidService)) { + TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This, debugstr_guid(riid), ppv); + + if(!This->init_authenticate) { + This->init_authenticate = TRUE; + hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IAuthenticate, + (void**)&This->authenticate); + if(FAILED(hres) && This->serv_prov) + IServiceProvider_QueryService(This->serv_prov, &IID_IAuthenticate, + &IID_IAuthenticate, (void**)&This->authenticate); + } + + 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; +} + +#undef SERVPROV_THIS + +static const IServiceProviderVtbl BSCServiceProviderVtbl = { + BSCServiceProvider_QueryInterface, + BSCServiceProvider_AddRef, + BSCServiceProvider_Release, + BSCServiceProvider_QueryService +}; + +#define HTTPNEG2_THIS(iface) DEFINE_THIS(BindStatusCallback, HttpNegotiate2, iface) + +static HRESULT WINAPI BSCHttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, + REFIID riid, void **ppv) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); +} + +static ULONG WINAPI BSCHttpNegotiate_AddRef(IHttpNegotiate2 *iface) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + return IBindStatusCallback_AddRef(STATUSCLB(This)); +} + +static ULONG WINAPI BSCHttpNegotiate_Release(IHttpNegotiate2 *iface) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + return IBindStatusCallback_Release(STATUSCLB(This)); +} + +static HRESULT WINAPI BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, + LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + + TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved, + pszAdditionalHeaders); + + *pszAdditionalHeaders = NULL; + + if(!This->http_negotiate) + return S_OK; + + return IHttpNegotiate_BeginningTransaction(This->http_negotiate, szURL, szHeaders, + dwReserved, pszAdditionalHeaders); +} + +static HRESULT WINAPI BSCHttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode, + LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, + LPWSTR *pszAdditionalRequestHeaders) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + LPWSTR additional_headers = NULL; + HRESULT hres = S_OK; + + TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders), + debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders); + + if(This->http_negotiate) + hres = IHttpNegotiate_OnResponse(This->http_negotiate, dwResponseCode, szResponseHeaders, + szRequestHeaders, &additional_headers); + + if(pszAdditionalRequestHeaders) + *pszAdditionalRequestHeaders = additional_headers; + else if(additional_headers) + CoTaskMemFree(additional_headers); + + return hres; +} + +static HRESULT WINAPI BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface, + BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + + TRACE("(%p)->(%p %p %ld)\n", This, pbSecurityId, pcbSecurityId, dwReserved); + + if(!This->http_negotiate2) + return E_FAIL; + + return IHttpNegotiate2_GetRootSecurityId(This->http_negotiate2, pbSecurityId, + pcbSecurityId, dwReserved); +} + +#undef HTTPNEG2_THIS + +static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl = { + BSCHttpNegotiate_QueryInterface, + BSCHttpNegotiate_AddRef, + BSCHttpNegotiate_Release, + BSCHttpNegotiate_BeginningTransaction, + BSCHttpNegotiate_OnResponse, + BSCHttpNegotiate_GetRootSecurityId +}; + +#define AUTHENTICATE_THIS(iface) DEFINE_THIS(BindStatusCallback, Authenticate, iface) + +static HRESULT WINAPI BSCAuthenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + return IBindStatusCallback_QueryInterface(AUTHENTICATE(This), riid, ppv); +} + +static ULONG WINAPI BSCAuthenticate_AddRef(IAuthenticate *iface) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + return IBindStatusCallback_AddRef(STATUSCLB(This)); +} + +static ULONG WINAPI BSCAuthenticate_Release(IAuthenticate *iface) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + return IBindStatusCallback_Release(STATUSCLB(This)); +} + +static HRESULT WINAPI BSCAuthenticate_Authenticate(IAuthenticate *iface, + HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + FIXME("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword); + return E_NOTIMPL; +} + +#undef AUTHENTICATE_THIS + +static const IAuthenticateVtbl BSCAuthenticateVtbl = { + BSCAuthenticate_QueryInterface, + BSCAuthenticate_AddRef, + BSCAuthenticate_Release, + BSCAuthenticate_Authenticate +}; + +static IBindStatusCallback *create_bsc(IBindStatusCallback *bsc) +{ + BindStatusCallback *ret = urlmon_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); +} + +/*********************************************************************** + * 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); + if(SUCCEEDED(hres)) { + hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder); + if(SUCCEEDED(hres)) { + prev = holder->callback; + IBindStatusCallback_AddRef(prev); + IBindStatusCallback_Release(bsc); + IBindStatusCallback_Release(STATUSCLB(holder)); + }else { + prev = bsc; + } + } + + IUnknown_Release(unk); + IBindCtx_RevokeObjectParam(pbc, BSCBHolder); + } + + bsc = create_bsc(pbsc); + hres = IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown*)bsc); + IBindStatusCallback_Release(bsc); + if(FAILED(hres)) { + IBindStatusCallback_Release(prev); + return hres; + } + + if(ppbscPrevious) + *ppbscPrevious = prev; + return S_OK; +} + +/*********************************************************************** + * 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; +} + +typedef struct { + const IBindCtxVtbl *lpBindCtxVtbl; + + LONG ref; + + IBindCtx *bindctx; +} AsyncBindCtx; + +#define BINDCTX(x) ((IBindCtx*) &(x)->lpBindCtxVtbl) + +#define BINDCTX_THIS(iface) DEFINE_THIS(AsyncBindCtx, BindCtx, iface) + +static HRESULT WINAPI AsyncBindCtx_QueryInterface(IBindCtx *iface, REFIID riid, void **ppv) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + + *ppv = NULL; + + if(IsEqualGUID(riid, &IID_IUnknown)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = BINDCTX(This); + }else if(IsEqualGUID(riid, &IID_IBindCtx)) { + TRACE("(%p)->(IID_IBindCtx %p)\n", This, ppv); + *ppv = BINDCTX(This); + }else if(IsEqualGUID(riid, &IID_IAsyncBindCtx)) { + TRACE("(%p)->(IID_IAsyncBindCtx %p)\n", This, ppv); + *ppv = BINDCTX(This); + } + + if(*ppv) { + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + } + + FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + return E_NOINTERFACE; +} + +static ULONG WINAPI AsyncBindCtx_AddRef(IBindCtx *iface) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI AsyncBindCtx_Release(IBindCtx *iface) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + IBindCtx_Release(This->bindctx); + urlmon_free(This); + } + + return ref; +} + +static HRESULT WINAPI AsyncBindCtx_RegisterObjectBound(IBindCtx *iface, IUnknown *punk) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + + TRACE("(%p)->(%p)\n", This, punk); + + return IBindCtx_RegisterObjectBound(This->bindctx, punk); +} + +static HRESULT WINAPI AsyncBindCtx_RevokeObjectBound(IBindCtx *iface, IUnknown *punk) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + + TRACE("(%p %p)\n", This, punk); + + return IBindCtx_RevokeObjectBound(This->bindctx, punk); +} + +static HRESULT WINAPI AsyncBindCtx_ReleaseBoundObjects(IBindCtx *iface) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + + TRACE("(%p)\n", This); + + return IBindCtx_ReleaseBoundObjects(This->bindctx); +} + +static HRESULT WINAPI AsyncBindCtx_SetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pbindopts); + + return IBindCtx_SetBindOptions(This->bindctx, pbindopts); +} + +static HRESULT WINAPI AsyncBindCtx_GetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pbindopts); + + return IBindCtx_GetBindOptions(This->bindctx, pbindopts); +} + +static HRESULT WINAPI AsyncBindCtx_GetRunningObjectTable(IBindCtx *iface, IRunningObjectTable **pprot) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pprot); + + return IBindCtx_GetRunningObjectTable(This->bindctx, pprot); +} + +static HRESULT WINAPI AsyncBindCtx_RegisterObjectParam(IBindCtx *iface, LPOLESTR pszkey, IUnknown *punk) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk); + + return IBindCtx_RegisterObjectParam(This->bindctx, pszkey, punk); +} + +static HRESULT WINAPI AsyncBindCtx_GetObjectParam(IBindCtx* iface, LPOLESTR pszkey, IUnknown **punk) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk); + + return IBindCtx_GetObjectParam(This->bindctx, pszkey, punk); +} + +static HRESULT WINAPI AsyncBindCtx_RevokeObjectParam(IBindCtx *iface, LPOLESTR ppenum) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + + TRACE("(%p)->(%p)\n", This, ppenum); + + return IBindCtx_RevokeObjectParam(This->bindctx, ppenum); +} + +static HRESULT WINAPI AsyncBindCtx_EnumObjectParam(IBindCtx *iface, IEnumString **pszkey) +{ + AsyncBindCtx *This = BINDCTX_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pszkey); + + return IBindCtx_EnumObjectParam(This->bindctx, pszkey); +} + +#undef BINDCTX_THIS + +static const IBindCtxVtbl AsyncBindCtxVtbl = +{ + AsyncBindCtx_QueryInterface, + AsyncBindCtx_AddRef, + AsyncBindCtx_Release, + AsyncBindCtx_RegisterObjectBound, + AsyncBindCtx_RevokeObjectBound, + AsyncBindCtx_ReleaseBoundObjects, + AsyncBindCtx_SetBindOptions, + AsyncBindCtx_GetBindOptions, + AsyncBindCtx_GetRunningObjectTable, + AsyncBindCtx_RegisterObjectParam, + AsyncBindCtx_GetObjectParam, + AsyncBindCtx_EnumObjectParam, + AsyncBindCtx_RevokeObjectParam +}; + +static HRESULT init_bindctx(IBindCtx *bindctx, DWORD options, + IBindStatusCallback *callback, IEnumFORMATETC *format) +{ + BIND_OPTS bindopts; + HRESULT hres; + + if(options) + FIXME("not supported options %08x\n", options); + if(format) + FIXME("format is not supported\n"); + + bindopts.cbStruct = sizeof(BIND_OPTS); + bindopts.grfFlags = BIND_MAYBOTHERUSER; + bindopts.grfMode = STGM_READWRITE | STGM_SHARE_EXCLUSIVE; + bindopts.dwTickCountDeadline = 0; + + hres = IBindCtx_SetBindOptions(bindctx, &bindopts); + if(FAILED(hres)) + return hres; + + if(callback) { + hres = RegisterBindStatusCallback(bindctx, callback, NULL, 0); + if(FAILED(hres)) + return hres; + } + + return S_OK; +} + +/*********************************************************************** + * CreateAsyncBindCtx (urlmon.@) + */ +HRESULT WINAPI CreateAsyncBindCtx(DWORD reserved, IBindStatusCallback *callback, + IEnumFORMATETC *format, IBindCtx **pbind) +{ + IBindCtx *bindctx; + HRESULT hres; + + TRACE("(%08x %p %p %p)\n", reserved, callback, format, pbind); + + if(!pbind || !callback) + return E_INVALIDARG; + + hres = CreateBindCtx(0, &bindctx); + if(FAILED(hres)) + return hres; + + hres = init_bindctx(bindctx, 0, callback, format); + if(FAILED(hres)) { + IBindCtx_Release(bindctx); + return hres; + } + + *pbind = bindctx; + return S_OK; +} + +/*********************************************************************** + * CreateAsyncBindCtxEx (urlmon.@) + * + * Create an asynchronous bind context. + */ +HRESULT WINAPI CreateAsyncBindCtxEx(IBindCtx *ibind, DWORD options, + IBindStatusCallback *callback, IEnumFORMATETC *format, IBindCtx** pbind, + DWORD reserved) +{ + AsyncBindCtx *ret; + IBindCtx *bindctx; + HRESULT hres; + + TRACE("(%p %08x %p %p %p %d)\n", ibind, options, callback, format, pbind, reserved); + + if(!pbind) + return E_INVALIDARG; + + if(reserved) + WARN("reserved=%d\n", reserved); + + hres = CreateBindCtx(0, &bindctx); + if(FAILED(hres)) + return hres; + + ret = urlmon_alloc(sizeof(AsyncBindCtx)); + + ret->lpBindCtxVtbl = &AsyncBindCtxVtbl; + ret->ref = 1; + ret->bindctx = bindctx; + + hres = init_bindctx(BINDCTX(ret), options, callback, format); + if(FAILED(hres)) { + IBindCtx_Release(BINDCTX(ret)); + return hres; + } + + *pbind = BINDCTX(ret); + return S_OK; +} diff --git a/reactos/dll/win32/urlmon/binding.c b/reactos/dll/win32/urlmon/binding.c index 43b5e04681b..121e01a5b93 100644 --- a/reactos/dll/win32/urlmon/binding.c +++ b/reactos/dll/win32/urlmon/binding.c @@ -45,15 +45,6 @@ typedef struct _task_header_t { struct _task_header_t *next; } task_header_t; -typedef struct { - const IHttpNegotiate2Vtbl *lpHttpNegotiate2Vtbl; - - LONG ref; - - IHttpNegotiate *http_negotiate; - IHttpNegotiate2 *http_negotiate2; -} HttpNegotiate2Wrapper; - typedef struct { const IStreamVtbl *lpStreamVtbl; @@ -85,7 +76,6 @@ struct Binding { IInternetProtocol *protocol; IServiceProvider *service_provider; ProtocolStream *stream; - HttpNegotiate2Wrapper *httpneg2_wrapper; BINDINFO bindinfo; DWORD bindf; @@ -122,10 +112,12 @@ static void push_task(Binding *binding, task_header_t *task, task_proc_t proc) EnterCriticalSection(&binding->section); - if(binding->task_queue_tail) + if(binding->task_queue_tail) { binding->task_queue_tail->next = task; - else + binding->task_queue_tail = task; + }else { binding->task_queue_tail = binding->task_queue_head = task; + } LeaveCriticalSection(&binding->section); } @@ -196,7 +188,7 @@ static HWND get_notif_hwnd(void) notif_wnd_proc, 0, 0, NULL, NULL, NULL, NULL, NULL, wszURLMonikerNotificationWindow, - NULL + NULL }; wndclass.hInstance = URLMON_hInstance; @@ -259,154 +251,6 @@ static void dump_BINDINFO(BINDINFO *bi) ); } -#define HTTPNEG2_THIS(iface) DEFINE_THIS(HttpNegotiate2Wrapper, HttpNegotiate2, iface) - -static HRESULT WINAPI HttpNegotiate2Wrapper_QueryInterface(IHttpNegotiate2 *iface, - REFIID riid, void **ppv) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - - *ppv = NULL; - - if(IsEqualGUID(&IID_IUnknown, riid)) { - TRACE("(IID_IUnknown %p)\n", ppv); - *ppv = HTTPNEG2(This); - }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) { - TRACE("(IID_IHttpNegotiate %p)\n", ppv); - *ppv = HTTPNEG2(This); - }else if(IsEqualGUID(&IID_IHttpNegotiate2, riid)) { - TRACE("(IID_IHttpNegotiate2 %p)\n", ppv); - *ppv = HTTPNEG2(This); - } - - if(*ppv) { - IHttpNegotiate2_AddRef(HTTPNEG2(This)); - return S_OK; - } - - WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); - return E_NOINTERFACE; -} - -static ULONG WINAPI HttpNegotiate2Wrapper_AddRef(IHttpNegotiate2 *iface) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%d\n", This, ref); - - return ref; -} - -static ULONG WINAPI HttpNegotiate2Wrapper_Release(IHttpNegotiate2 *iface) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%d\n", This, ref); - - if(!ref) { - if (This->http_negotiate) - IHttpNegotiate_Release(This->http_negotiate); - if (This->http_negotiate2) - IHttpNegotiate2_Release(This->http_negotiate2); - HeapFree(GetProcessHeap(), 0, This); - - URLMON_UnlockModule(); - } - - return ref; -} - -static HRESULT WINAPI HttpNegotiate2Wrapper_BeginningTransaction(IHttpNegotiate2 *iface, - LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - - TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved, - pszAdditionalHeaders); - - if(This->http_negotiate) - return IHttpNegotiate_BeginningTransaction(This->http_negotiate, szURL, szHeaders, - dwReserved, pszAdditionalHeaders); - - *pszAdditionalHeaders = NULL; - return S_OK; -} - -static HRESULT WINAPI HttpNegotiate2Wrapper_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode, - LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, - LPWSTR *pszAdditionalRequestHeaders) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - LPWSTR szAdditionalRequestHeaders = NULL; - HRESULT hres = S_OK; - - TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders), - debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders); - - /* IHttpNegotiate2_OnResponse expects pszAdditionalHeaders to be non-NULL when it is - * implemented as part of IBindStatusCallback, but it is NULL when called directly from - * IProtocol */ - if(!pszAdditionalRequestHeaders) - pszAdditionalRequestHeaders = &szAdditionalRequestHeaders; - - if(This->http_negotiate) - { - hres = IHttpNegotiate_OnResponse(This->http_negotiate, dwResponseCode, szResponseHeaders, - szRequestHeaders, pszAdditionalRequestHeaders); - if(pszAdditionalRequestHeaders == &szAdditionalRequestHeaders && - szAdditionalRequestHeaders) - CoTaskMemFree(szAdditionalRequestHeaders); - } - else - { - *pszAdditionalRequestHeaders = NULL; - } - - return hres; -} - -static HRESULT WINAPI HttpNegotiate2Wrapper_GetRootSecurityId(IHttpNegotiate2 *iface, - BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - - TRACE("(%p)->(%p %p %ld)\n", This, pbSecurityId, pcbSecurityId, dwReserved); - - if (This->http_negotiate2) - return IHttpNegotiate2_GetRootSecurityId(This->http_negotiate2, pbSecurityId, - pcbSecurityId, dwReserved); - - /* That's all we have to do here */ - return E_FAIL; -} - -#undef HTTPNEG2_THIS - -static const IHttpNegotiate2Vtbl HttpNegotiate2WrapperVtbl = { - HttpNegotiate2Wrapper_QueryInterface, - HttpNegotiate2Wrapper_AddRef, - HttpNegotiate2Wrapper_Release, - HttpNegotiate2Wrapper_BeginningTransaction, - HttpNegotiate2Wrapper_OnResponse, - HttpNegotiate2Wrapper_GetRootSecurityId -}; - -static HttpNegotiate2Wrapper *create_httpneg2_wrapper(void) -{ - HttpNegotiate2Wrapper *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(HttpNegotiate2Wrapper)); - - ret->lpHttpNegotiate2Vtbl = &HttpNegotiate2WrapperVtbl; - ret->ref = 1; - ret->http_negotiate = NULL; - ret->http_negotiate2 = NULL; - - URLMON_LockModule(); - - return ret; -} - #define STREAM_THIS(iface) DEFINE_THIS(ProtocolStream, Stream, iface) static HRESULT WINAPI ProtocolStream_QueryInterface(IStream *iface, @@ -455,7 +299,7 @@ static ULONG WINAPI ProtocolStream_Release(IStream *iface) if(!ref) { IInternetProtocol_Release(This->protocol); - HeapFree(GetProcessHeap(), 0, This); + urlmon_free(This); URLMON_UnlockModule(); } @@ -485,12 +329,14 @@ static HRESULT WINAPI ProtocolStream_Read(IStream *iface, void *pv, } if(read == cb) { - *pcbRead = read; + if (pcbRead) + *pcbRead = read; return S_OK; } This->hres = IInternetProtocol_Read(This->protocol, (PBYTE)pv+read, cb-read, &pread); - *pcbRead = read + pread; + if (pcbRead) + *pcbRead = read + pread; if(This->hres == E_PENDING) return E_PENDING; @@ -605,7 +451,7 @@ static const IStreamVtbl ProtocolStreamVtbl = { static ProtocolStream *create_stream(IInternetProtocol *protocol) { - ProtocolStream *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(ProtocolStream)); + ProtocolStream *ret = urlmon_alloc(sizeof(ProtocolStream)); ret->lpStreamVtbl = &ProtocolStreamVtbl; ret->ref = 1; @@ -681,16 +527,14 @@ static ULONG WINAPI Binding_Release(IBinding *iface) IServiceProvider_Release(This->service_provider); if(This->stream) IStream_Release(STREAM(This->stream)); - if(This->httpneg2_wrapper) - IHttpNegotiate2_Release(HTTPNEG2(This->httpneg2_wrapper)); ReleaseBindInfo(&This->bindinfo); This->section.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->section); - HeapFree(GetProcessHeap(), 0, This->mime); - HeapFree(GetProcessHeap(), 0, This->url); + urlmon_free(This->mime); + urlmon_free(This->url); - HeapFree(GetProcessHeap(), 0, This); + urlmon_free(This); URLMON_UnlockModule(); } @@ -778,16 +622,16 @@ static ULONG WINAPI InternetProtocolSink_Release(IInternetProtocolSink *iface) typedef struct { task_header_t header; - PROTOCOLDATA *data; + PROTOCOLDATA data; } switch_task_t; static void switch_proc(Binding *binding, task_header_t *t) { switch_task_t *task = (switch_task_t*)t; - IInternetProtocol_Continue(binding->protocol, task->data); + IInternetProtocol_Continue(binding->protocol, &task->data); - HeapFree(GetProcessHeap(), 0, task); + urlmon_free(task); } static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface, @@ -798,8 +642,8 @@ static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface, TRACE("(%p)->(%p)\n", This, pProtocolData); - task = HeapAlloc(GetProcessHeap(), 0, sizeof(switch_task_t)); - task->data = pProtocolData; + task = urlmon_alloc(sizeof(switch_task_t)); + memcpy(&task->data, pProtocolData, sizeof(PROTOCOLDATA)); push_task(This, &task->header, switch_proc); @@ -826,8 +670,8 @@ static void on_progress_proc(Binding *binding, task_header_t *t) IBindStatusCallback_OnProgress(binding->callback, task->progress, task->progress_max, task->status_code, task->status_text); - HeapFree(GetProcessHeap(), 0, task->status_text); - HeapFree(GetProcessHeap(), 0, task); + urlmon_free(task->status_text); + urlmon_free(task); } static void on_progress(Binding *This, ULONG progress, ULONG progress_max, @@ -841,7 +685,7 @@ static void on_progress(Binding *This, ULONG progress, ULONG progress_max, return; } - task = HeapAlloc(GetProcessHeap(), 0, sizeof(on_progress_task_t)); + task = urlmon_alloc(sizeof(on_progress_task_t)); task->progress = progress; task->progress_max = progress_max; @@ -850,7 +694,7 @@ static void on_progress(Binding *This, ULONG progress, ULONG progress_max, if(status_text) { DWORD size = (strlenW(status_text)+1)*sizeof(WCHAR); - task->status_text = HeapAlloc(GetProcessHeap(), 0, size); + task->status_text = urlmon_alloc(size); memcpy(task->status_text, status_text, size); }else { task->status_text = NULL; @@ -883,7 +727,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink break; case BINDSTATUS_MIMETYPEAVAILABLE: { int len = strlenW(szStatusText)+1; - This->mime = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + This->mime = urlmon_alloc(len*sizeof(WCHAR)); memcpy(This->mime, szStatusText, len*sizeof(WCHAR)); break; } @@ -910,6 +754,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progress_max) { FORMATETC formatetc = {0, NULL, 1, -1, TYMED_ISTREAM}; + BOOL sent_begindownloaddata = FALSE; TRACE("(%p)->(%d %u %u)\n", This, bscf, progress, progress_max); @@ -937,13 +782,18 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres fill_stream_buffer(This->stream); This->download_state = DOWNLOADING; + sent_begindownloaddata = TRUE; IBindStatusCallback_OnProgress(This->callback, progress, progress_max, BINDSTATUS_BEGINDOWNLOADDATA, This->url); } if(This->stream->hres == S_FALSE || (bscf & BSCF_LASTDATANOTIFICATION)) { + This->download_state = END_DOWNLOAD; IBindStatusCallback_OnProgress(This->callback, progress, progress_max, BINDSTATUS_ENDDOWNLOADDATA, This->url); + }else if(!sent_begindownloaddata) { + IBindStatusCallback_OnProgress(This->callback, progress, progress_max, + BINDSTATUS_DOWNLOADINGDATA, This->url); } if(!This->request_locked) { @@ -951,13 +801,10 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres This->request_locked = SUCCEEDED(hres); } - fill_stream_buffer(This->stream); - - IBindStatusCallback_OnDataAvailable(This->callback, bscf, This->stream->buf_size, + IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress, &formatetc, &This->stgmed); - if(This->stream->hres == S_FALSE) { - This->download_state = END_DOWNLOAD; + if(This->download_state == END_DOWNLOAD) { IBindStatusCallback_OnStopBinding(This->callback, S_OK, NULL); } } @@ -975,7 +822,7 @@ static void report_data_proc(Binding *binding, task_header_t *t) report_data(binding, task->bscf, task->progress, task->progress_max); - HeapFree(GetProcessHeap(), 0, task); + urlmon_free(task); } static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *iface, @@ -989,7 +836,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *ifa FIXME("called from worked hread\n"); if(This->continue_call) { - report_data_task_t *task = HeapAlloc(GetProcessHeap(), 0, sizeof(report_data_task_t)); + report_data_task_t *task = urlmon_alloc(sizeof(report_data_task_t)); task->bscf = grfBSCF; task->progress = ulProgress; task->progress_max = ulProgressMax; @@ -1011,7 +858,7 @@ static void report_result_proc(Binding *binding, task_header_t *t) binding->request_locked = FALSE; } - HeapFree(GetProcessHeap(), 0, t); + urlmon_free(t); } static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *iface, @@ -1024,7 +871,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *i if(GetCurrentThreadId() == This->apartment_thread && !This->continue_call) { IInternetProtocol_Terminate(This->protocol, 0); }else { - task_header_t *task = HeapAlloc(GetProcessHeap(), 0, sizeof(task_header_t)); + task_header_t *task = urlmon_alloc(sizeof(task_header_t)); push_task(This, task, report_result_proc); } @@ -1173,22 +1020,6 @@ static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, return hres; } - if(IsEqualGUID(&IID_IHttpNegotiate, guidService) - || IsEqualGUID(&IID_IHttpNegotiate2, guidService)) { - if(!This->httpneg2_wrapper) { - WARN("HttpNegotiate2Wrapper expected to be non-NULL\n"); - } else { - if(IsEqualGUID(&IID_IHttpNegotiate, guidService)) - IBindStatusCallback_QueryInterface(This->callback, riid, - (void **)&This->httpneg2_wrapper->http_negotiate); - else - IBindStatusCallback_QueryInterface(This->callback, riid, - (void **)&This->httpneg2_wrapper->http_negotiate2); - - return IHttpNegotiate2_QueryInterface(HTTPNEG2(This->httpneg2_wrapper), riid, ppv); - } - } - WARN("unknown service %s\n", debugstr_guid(guidService)); return E_NOTIMPL; } @@ -1204,15 +1035,18 @@ static const IServiceProviderVtbl ServiceProviderVtbl = { static HRESULT get_callback(IBindCtx *pbc, IBindStatusCallback **callback) { + IUnknown *unk; HRESULT hres; static WCHAR wszBSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 }; - hres = IBindCtx_GetObjectParam(pbc, wszBSCBHolder, (IUnknown**)callback); - if(FAILED(hres)) - return MK_E_SYNTAX; + hres = IBindCtx_GetObjectParam(pbc, wszBSCBHolder, &unk); + if(SUCCEEDED(hres)) { + hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)callback); + IUnknown_Release(unk); + } - return S_OK; + return SUCCEEDED(hres) ? S_OK : MK_E_SYNTAX; } static HRESULT get_protocol(Binding *This, LPCWSTR url) @@ -1289,7 +1123,7 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding * URLMON_LockModule(); - ret = HeapAlloc(GetProcessHeap(), 0, sizeof(Binding)); + ret = urlmon_alloc(sizeof(Binding)); ret->lpBindingVtbl = &BindingVtbl; ret->lpInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl; @@ -1302,7 +1136,6 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding * ret->protocol = NULL; ret->service_provider = NULL; ret->stream = NULL; - ret->httpneg2_wrapper = NULL; ret->mime = NULL; ret->url = NULL; ret->apartment_thread = GetCurrentThreadId(); @@ -1352,7 +1185,7 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding * ret->bindf |= BINDF_NEEDFILE; len = strlenW(url)+1; - ret->url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + ret->url = urlmon_alloc(len*sizeof(WCHAR)); memcpy(ret->url, url, len*sizeof(WCHAR)); ret->stream = create_stream(ret->protocol); @@ -1360,8 +1193,6 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding * ret->stgmed.u.pstm = STREAM(ret->stream); ret->stgmed.pUnkForRelease = (IUnknown*)BINDING(ret); /* NOTE: Windows uses other IUnknown */ - ret->httpneg2_wrapper = create_httpneg2_wrapper(); - *binding = ret; return S_OK; } @@ -1370,6 +1201,7 @@ HRESULT start_binding(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv) { Binding *binding = NULL; HRESULT hres; + MSG msg; *ppv = NULL; @@ -1398,6 +1230,15 @@ HRESULT start_binding(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv) return hres; } + while(!(binding->bindf & BINDF_ASYNCHRONOUS) && + binding->download_state != END_DOWNLOAD) { + MsgWaitForMultipleObjects(0, NULL, FALSE, 5000, QS_POSTMESSAGE); + while (PeekMessageW(&msg, binding->notif_hwnd, WM_USER, WM_USER+117, PM_REMOVE|PM_NOYIELD)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + if(binding->stream->init_buf) { if(binding->request_locked) IInternetProtocol_UnlockRequest(binding->protocol); diff --git a/reactos/dll/win32/urlmon/bindprot.c b/reactos/dll/win32/urlmon/bindprot.c index 6b175f630c6..5c5271967cd 100644 --- a/reactos/dll/win32/urlmon/bindprot.c +++ b/reactos/dll/win32/urlmon/bindprot.c @@ -114,7 +114,7 @@ static ULONG WINAPI BindProtocol_Release(IInternetProtocol *iface) if(This->protocol_sink) IInternetProtocolSink_Release(This->protocol_sink); - HeapFree(GetProcessHeap(), 0, This); + urlmon_free(This); URLMON_UnlockModule(); } @@ -480,7 +480,7 @@ static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = { HRESULT create_binding_protocol(LPCWSTR url, IInternetProtocol **protocol) { - BindProtocol *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(BindProtocol)); + BindProtocol *ret = urlmon_alloc(sizeof(BindProtocol)); ret->lpInternetProtocolVtbl = &BindProtocolVtbl; ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl; diff --git a/reactos/dll/win32/urlmon/file.c b/reactos/dll/win32/urlmon/file.c index 4951798195a..8e4fb1c8fa3 100644 --- a/reactos/dll/win32/urlmon/file.c +++ b/reactos/dll/win32/urlmon/file.c @@ -92,7 +92,7 @@ static ULONG WINAPI FileProtocol_Release(IInternetProtocol *iface) if(!ref) { if(This->file) CloseHandle(This->file); - HeapFree(GetProcessHeap(), 0, This); + urlmon_free(This); URLMON_UnlockModule(); } @@ -135,10 +135,10 @@ static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl return MK_E_SYNTAX; len = lstrlenW(szUrl)+16; - url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + url = urlmon_alloc(len*sizeof(WCHAR)); hres = CoInternetParseUrl(szUrl, PARSE_ENCODE, 0, url, len, &len, 0); if(FAILED(hres)) { - HeapFree(GetProcessHeap(), 0, url); + urlmon_free(url); return hres; } @@ -163,7 +163,7 @@ static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl This->file = NULL; IInternetProtocolSink_ReportResult(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, GetLastError(), NULL); - HeapFree(GetProcessHeap(), 0, url); + urlmon_free(url); return INET_E_RESOURCE_NOT_FOUND; } @@ -180,7 +180,7 @@ static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl } } - HeapFree(GetProcessHeap(), 0, url); + urlmon_free(url); if(GetFileSizeEx(This->file, &size)) IInternetProtocolSink_ReportData(pOIProtSink, @@ -246,7 +246,7 @@ static HRESULT WINAPI FileProtocol_Read(IInternetProtocol *iface, void *pv, if(pcbRead) *pcbRead = read; - + return cb == read ? S_OK : S_FALSE; } @@ -353,7 +353,7 @@ HRESULT FileProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) URLMON_LockModule(); - ret = HeapAlloc(GetProcessHeap(), 0, sizeof(FileProtocol)); + ret = urlmon_alloc(sizeof(FileProtocol)); ret->lpInternetProtocolVtbl = &FileProtocolVtbl; ret->lpInternetPriorityVtbl = &FilePriorityVtbl; @@ -362,6 +362,6 @@ HRESULT FileProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) ret->ref = 1; *ppobj = PROTOCOL(ret); - + return S_OK; } diff --git a/reactos/dll/win32/urlmon/format.c b/reactos/dll/win32/urlmon/format.c index 0a0a97d5cf0..d9fce939c22 100644 --- a/reactos/dll/win32/urlmon/format.c +++ b/reactos/dll/win32/urlmon/format.c @@ -43,7 +43,7 @@ typedef struct { LONG ref; } EnumFORMATETC; -static IEnumFORMATETC *EnumFORMATETC_Create(UINT cfmtetc, FORMATETC *rgfmtetc, UINT it); +static IEnumFORMATETC *EnumFORMATETC_Create(UINT cfmtetc, const FORMATETC *rgfmtetc, UINT it); #define ENUMF_THIS(iface) ICOM_THIS_MULTI(EnumFORMATETC, lpEnumFORMATETCVtbl, iface) @@ -78,8 +78,8 @@ static ULONG WINAPI EnumFORMATETC_Release(IEnumFORMATETC *iface) TRACE("(%p) ref=%d\n", This, ref); if(!ref) { - HeapFree(GetProcessHeap(), 0, This->fetc); - HeapFree(GetProcessHeap(), 0, This); + urlmon_free(This->fetc); + urlmon_free(This); URLMON_UnlockModule(); } @@ -158,9 +158,9 @@ static const IEnumFORMATETCVtbl EnumFORMATETCVtbl = { EnumFORMATETC_Clone }; -static IEnumFORMATETC *EnumFORMATETC_Create(UINT cfmtetc, FORMATETC *rgfmtetc, UINT it) +static IEnumFORMATETC *EnumFORMATETC_Create(UINT cfmtetc, const FORMATETC *rgfmtetc, UINT it) { - EnumFORMATETC *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumFORMATETC)); + EnumFORMATETC *ret = urlmon_alloc(sizeof(EnumFORMATETC)); URLMON_LockModule(); @@ -169,7 +169,7 @@ static IEnumFORMATETC *EnumFORMATETC_Create(UINT cfmtetc, FORMATETC *rgfmtetc, U ret->it = it; ret->fetc_cnt = cfmtetc; - ret->fetc = HeapAlloc(GetProcessHeap(), 0, cfmtetc*sizeof(FORMATETC)); + ret->fetc = urlmon_alloc(cfmtetc*sizeof(FORMATETC)); memcpy(ret->fetc, rgfmtetc, cfmtetc*sizeof(FORMATETC)); return (IEnumFORMATETC*)ret; diff --git a/reactos/dll/win32/urlmon/ftp.c b/reactos/dll/win32/urlmon/ftp.c index 33fe5671935..e71789c3e9f 100644 --- a/reactos/dll/win32/urlmon/ftp.c +++ b/reactos/dll/win32/urlmon/ftp.c @@ -81,7 +81,7 @@ static ULONG WINAPI FtpProtocol_Release(IInternetProtocol *iface) TRACE("(%p) ref=%d\n", This, ref); if(!ref) { - HeapFree(GetProcessHeap(), 0, This); + urlmon_free(This); URLMON_UnlockModule(); } @@ -191,12 +191,12 @@ HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) URLMON_LockModule(); - ret = HeapAlloc(GetProcessHeap(), 0, sizeof(FtpProtocol)); + ret = urlmon_alloc(sizeof(FtpProtocol)); ret->lpInternetProtocolVtbl = &FtpProtocolVtbl; ret->ref = 1; *ppobj = PROTOCOL(ret); - + return S_OK; } diff --git a/reactos/dll/win32/urlmon/http.c b/reactos/dll/win32/urlmon/http.c index e7297cfa94a..a743333a4d0 100644 --- a/reactos/dll/win32/urlmon/http.c +++ b/reactos/dll/win32/urlmon/http.c @@ -25,6 +25,7 @@ #include #define COBJMACROS +#define NONAMELESSUNION #include "windef.h" #include "winbase.h" @@ -141,26 +142,15 @@ static void HTTPPROTOCOL_AllDataRead(HttpProtocol *This) static void HTTPPROTOCOL_Close(HttpProtocol *This) { - if (This->protocol_sink) - { - IInternetProtocolSink_Release(This->protocol_sink); - This->protocol_sink = 0; - } if (This->http_negotiate) { IHttpNegotiate_Release(This->http_negotiate); This->http_negotiate = 0; } if (This->request) - { InternetCloseHandle(This->request); - This->request = 0; - } if (This->connect) - { InternetCloseHandle(This->connect); - This->connect = 0; - } if (This->internet) { InternetCloseHandle(This->internet); @@ -169,14 +159,9 @@ static void HTTPPROTOCOL_Close(HttpProtocol *This) if (This->full_header) { if (This->full_header != wszHeaders) - HeapFree(GetProcessHeap(), 0, This->full_header); + urlmon_free(This->full_header); This->full_header = 0; } - if (This->bind_info.cbSize) - { - ReleaseBindInfo(&This->bind_info); - memset(&This->bind_info, 0, sizeof(This->bind_info)); - } This->flags = 0; } @@ -213,6 +198,30 @@ static void CALLBACK HTTPPROTOCOL_InternetStatusCallback( else IInternetProtocol_Continue((IInternetProtocol *)This, &data); return; + case INTERNET_STATUS_HANDLE_CREATED: + IInternetProtocol_AddRef((IInternetProtocol *)This); + return; + case INTERNET_STATUS_HANDLE_CLOSING: + if (*(HINTERNET *)lpvStatusInformation == This->connect) + { + This->connect = 0; + } + else if (*(HINTERNET *)lpvStatusInformation == This->request) + { + This->request = 0; + if (This->protocol_sink) + { + IInternetProtocolSink_Release(This->protocol_sink); + This->protocol_sink = 0; + } + if (This->bind_info.cbSize) + { + ReleaseBindInfo(&This->bind_info); + memset(&This->bind_info, 0, sizeof(This->bind_info)); + } + } + IInternetProtocol_Release((IInternetProtocol *)This); + return; default: WARN("Unhandled Internet status callback %d\n", dwInternetStatus); return; @@ -221,11 +230,11 @@ static void CALLBACK HTTPPROTOCOL_InternetStatusCallback( IInternetProtocolSink_ReportProgress(This->protocol_sink, ulStatusCode, (LPWSTR)lpvStatusInformation); } -static inline LPWSTR strndupW(LPWSTR string, int len) +static inline LPWSTR strndupW(LPCWSTR string, int len) { LPWSTR ret = NULL; if (string && - (ret = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR))) != NULL) + (ret = urlmon_alloc((len+1)*sizeof(WCHAR))) != NULL) { memcpy(ret, string, len*sizeof(WCHAR)); ret[len] = 0; @@ -287,7 +296,7 @@ static ULONG WINAPI HttpProtocol_Release(IInternetProtocol *iface) if(!ref) { HTTPPROTOCOL_Close(This); - HeapFree(GetProcessHeap(), 0, This); + urlmon_free(This); URLMON_UnlockModule(); } @@ -320,6 +329,9 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink, pOIBindInfo, grfPI, dwReserved); + IInternetProtocolSink_AddRef(pOIProtSink); + This->protocol_sink = pOIProtSink; + memset(&This->bind_info, 0, sizeof(This->bind_info)); This->bind_info.cbSize = sizeof(BINDINFO); hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &This->grfBINDF, &This->bind_info); @@ -353,7 +365,7 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl url.nPort = INTERNET_DEFAULT_HTTP_PORT; if(!(This->grfBINDF & BINDF_FROMURLMON)) - IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL); + IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_DIRECTBIND, NULL); hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT, &user_agent, 1, &num); @@ -366,7 +378,7 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl { WARN("ObtainUserAgentString failed: %08x\n", hres); } - else if (!(user_agenta = HeapAlloc(GetProcessHeap(), 0, len*sizeof(CHAR)))) + else if (!(user_agenta = urlmon_alloc(len*sizeof(CHAR)))) { WARN("Out of memory\n"); } @@ -381,7 +393,7 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl else MultiByteToWideChar(CP_ACP, 0, user_agenta, -1, user_agent, len*sizeof(WCHAR)); } - HeapFree(GetProcessHeap(), 0, user_agenta); + urlmon_free(user_agenta); } This->internet = InternetOpenW(user_agent, 0, NULL, NULL, INTERNET_FLAG_ASYNC); @@ -392,9 +404,6 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl goto done; } - IInternetProtocolSink_AddRef(pOIProtSink); - This->protocol_sink = pOIProtSink; - /* Native does not check for success of next call, so we won't either */ InternetSetStatusCallbackW(This->internet, HTTPPROTOCOL_InternetStatusCallback); @@ -433,7 +442,7 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl goto done; } - hres = IInternetProtocolSink_QueryInterface(pOIProtSink, &IID_IServiceProvider, + hres = IInternetProtocolSink_QueryInterface(This->protocol_sink, &IID_IServiceProvider, (void **)&service_provider); if (hres != S_OK) { @@ -463,8 +472,7 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl else { int len_addl_header = lstrlenW(addl_header); - This->full_header = HeapAlloc(GetProcessHeap(), 0, - len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders)); + This->full_header = urlmon_alloc(len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders)); if (!This->full_header) { WARN("Out of memory\n"); @@ -516,7 +524,7 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl WARN("Expected This->bind_info.stgmedData.tymed to be TYMED_HGLOBAL, not %d\n", This->bind_info.stgmedData.tymed); else - optional = (LPWSTR)This->bind_info.stgmedData.hGlobal; + optional = (LPWSTR)This->bind_info.stgmedData.u.hGlobal; } if (!HttpSendRequestW(This->request, This->full_header, lstrlenW(This->full_header), optional, @@ -532,7 +540,7 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl done: if (hres != S_OK) { - IInternetProtocolSink_ReportResult(pOIProtSink, hres, 0, NULL); + IInternetProtocolSink_ReportResult(This->protocol_sink, hres, 0, NULL); HTTPPROTOCOL_Close(This); } @@ -548,10 +556,10 @@ done: CoTaskMemFree(accept_mimes[num++]); CoTaskMemFree(user_agent); - HeapFree(GetProcessHeap(), 0, pass); - HeapFree(GetProcessHeap(), 0, user); - HeapFree(GetProcessHeap(), 0, path); - HeapFree(GetProcessHeap(), 0, host); + urlmon_free(pass); + urlmon_free(user); + urlmon_free(path); + urlmon_free(host); return hres; } @@ -601,7 +609,7 @@ static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDA if ((!HttpQueryInfoW(This->request, HTTP_QUERY_RAW_HEADERS_CRLF, response_headers, &len, NULL) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) || - !(response_headers = HeapAlloc(GetProcessHeap(), 0, len)) || + !(response_headers = urlmon_alloc(len)) || !HttpQueryInfoW(This->request, HTTP_QUERY_RAW_HEADERS_CRLF, response_headers, &len, NULL)) { @@ -622,7 +630,7 @@ static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDA len = 0; if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type, &len, NULL) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) || - !(content_type = HeapAlloc(GetProcessHeap(), 0, len)) || + !(content_type = urlmon_alloc(len)) || !HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type, &len, NULL)) { WARN("HttpQueryInfo failed: %d\n", GetLastError()); @@ -634,6 +642,10 @@ static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDA } else { + /* remove the charset, if present */ + LPWSTR p = strchrW(content_type, ';'); + if (p) *p = '\0'; + IInternetProtocolSink_ReportProgress(This->protocol_sink, (This->grfBINDF & BINDF_FROMURLMON) ? BINDSTATUS_MIMETYPEAVAILABLE : @@ -644,7 +656,7 @@ static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDA len = 0; if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length, &len, NULL) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) || - !(content_length = HeapAlloc(GetProcessHeap(), 0, len)) || + !(content_length = urlmon_alloc(len)) || !HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length, &len, NULL)) { WARN("HttpQueryInfo failed: %d\n", GetLastError()); @@ -660,28 +672,30 @@ static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDA if (pProtocolData->pData >= (LPVOID)BINDSTATUS_DOWNLOADINGDATA) { + /* InternetQueryDataAvailable may immediately fork and perform its asynchronous + * read, so clear the flag _before_ calling so it does not incorrectly get cleared + * after the status callback is called */ + This->flags &= ~FLAG_REQUEST_COMPLETE; if (!InternetQueryDataAvailable(This->request, &This->available_bytes, 0, 0)) { - if (GetLastError() == ERROR_IO_PENDING) - { - This->flags &= ~FLAG_REQUEST_COMPLETE; - } - else + if (GetLastError() != ERROR_IO_PENDING) { + This->flags |= FLAG_REQUEST_COMPLETE; WARN("InternetQueryDataAvailable failed: %d\n", GetLastError()); HTTPPROTOCOL_ReportResult(This, INET_E_DATA_NOT_AVAILABLE); } } else { + This->flags |= FLAG_REQUEST_COMPLETE; HTTPPROTOCOL_ReportData(This); } } done: - HeapFree(GetProcessHeap(), 0, response_headers); - HeapFree(GetProcessHeap(), 0, content_type); - HeapFree(GetProcessHeap(), 0, content_length); + urlmon_free(response_headers); + urlmon_free(content_type); + urlmon_free(content_length); /* Returns S_OK on native */ return S_OK; @@ -911,7 +925,7 @@ HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) URLMON_LockModule(); - ret = HeapAlloc(GetProcessHeap(), 0, sizeof(HttpProtocol)); + ret = urlmon_alloc(sizeof(HttpProtocol)); ret->lpInternetProtocolVtbl = &HttpProtocolVtbl; ret->lpInternetPriorityVtbl = &HttpPriorityVtbl; @@ -927,6 +941,12 @@ HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) ret->ref = 1; *ppobj = PROTOCOL(ret); - + return S_OK; } + +HRESULT HttpSProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) +{ + FIXME("(%p %p)\n", pUnkOuter, ppobj); + return E_NOINTERFACE; +} diff --git a/reactos/dll/win32/urlmon/internet.c b/reactos/dll/win32/urlmon/internet.c index 5a42532b147..26269823610 100644 --- a/reactos/dll/win32/urlmon/internet.c +++ b/reactos/dll/win32/urlmon/internet.c @@ -43,7 +43,7 @@ static HRESULT parse_schema(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, if(flags) ERR("wrong flags\n"); - + ptr = strchrW(url, ':'); if(ptr) len = ptr-url; @@ -219,7 +219,7 @@ HRESULT WINAPI CoInternetCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, IInternetProtocolInfo *protocol_info; DWORD size = cchResult; HRESULT hres; - + TRACE("(%s,%s,0x%08x,%p,%d,%p,%d)\n", debugstr_w(pwzBaseUrl), debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved); diff --git a/reactos/dll/win32/urlmon/mk.c b/reactos/dll/win32/urlmon/mk.c index 2af01f2a0fc..766b50ea762 100644 --- a/reactos/dll/win32/urlmon/mk.c +++ b/reactos/dll/win32/urlmon/mk.c @@ -88,7 +88,7 @@ static ULONG WINAPI MkProtocol_Release(IInternetProtocol *iface) if(This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This); + urlmon_free(This); URLMON_UnlockModule(); } @@ -122,6 +122,9 @@ static HRESULT WINAPI MkProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink, pOIBindInfo, grfPI, dwReserved); + if(strncmpiW(szUrl, wszMK, sizeof(wszMK)/sizeof(WCHAR))) + return INET_E_INVALID_URL; + memset(&bindinfo, 0, sizeof(bindinfo)); bindinfo.cbSize = sizeof(BINDINFO); hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo); @@ -132,9 +135,6 @@ static HRESULT WINAPI MkProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, ReleaseBindInfo(&bindinfo); - if(strncmpiW(szUrl, wszMK, sizeof(wszMK)/sizeof(WCHAR))) - return MK_E_SYNTAX; - IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL); IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, NULL); @@ -153,11 +153,11 @@ static HRESULT WINAPI MkProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, if(!ptr) return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER); - progid = HeapAlloc(GetProcessHeap(), 0, (ptr-ptr2+1)*sizeof(WCHAR)); + progid = urlmon_alloc((ptr-ptr2+1)*sizeof(WCHAR)); memcpy(progid, ptr2, (ptr-ptr2)*sizeof(WCHAR)); progid[ptr-ptr2] = 0; hres = CLSIDFromProgID(progid, &clsid); - HeapFree(GetProcessHeap(), 0, progid); + urlmon_free(progid); if(FAILED(hres)) return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER); @@ -169,10 +169,10 @@ static HRESULT WINAPI MkProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, } len = strlenW(--ptr2); - display_name = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR)); + display_name = urlmon_alloc((len+1)*sizeof(WCHAR)); memcpy(display_name, ptr2, (len+1)*sizeof(WCHAR)); hres = IParseDisplayName_ParseDisplayName(pdn, NULL /* FIXME */, display_name, &eaten, &mon); - HeapFree(GetProcessHeap(), 0, display_name); + urlmon_free(display_name); IParseDisplayName_Release(pdn); if(FAILED(hres)) { WARN("ParseDisplayName failed: %08x\n", hres); @@ -307,7 +307,7 @@ HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) URLMON_LockModule(); - ret = HeapAlloc(GetProcessHeap(), 0, sizeof(MkProtocol)); + ret = urlmon_alloc(sizeof(MkProtocol)); ret->lpInternetProtocolVtbl = &MkProtocolVtbl; ret->ref = 1; diff --git a/reactos/dll/win32/urlmon/regsvr.c b/reactos/dll/win32/urlmon/regsvr.c index 64eb1a78dc2..eaf86b3d485 100644 --- a/reactos/dll/win32/urlmon/regsvr.c +++ b/reactos/dll/win32/urlmon/regsvr.c @@ -121,9 +121,6 @@ static LONG register_key_defvalueA(HKEY base, WCHAR const *name, static LONG register_progid(WCHAR const *clsid, char const *progid, char const *curver_progid, char const *name, char const *extra); -static LONG recursive_delete_key(HKEY key); -static LONG recursive_delete_keyA(HKEY base, char const *name); -static LONG recursive_delete_keyW(HKEY base, WCHAR const *name); /*********************************************************************** * register_interfaces @@ -212,7 +209,8 @@ static HRESULT unregister_interfaces(struct regsvr_interface const *list) WCHAR buf[39]; StringFromGUID2(list->iid, buf, 39); - res = recursive_delete_keyW(interface_key, buf); + res = RegDeleteTreeW(interface_key, buf); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; } RegCloseKey(interface_key); @@ -319,16 +317,19 @@ static HRESULT unregister_coclasses(struct regsvr_coclass const *list) WCHAR buf[39]; StringFromGUID2(list->clsid, buf, 39); - res = recursive_delete_keyW(coclass_key, buf); + res = RegDeleteTreeW(coclass_key, buf); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; if (res != ERROR_SUCCESS) goto error_close_coclass_key; if (list->progid) { - res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid); + res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; if (res != ERROR_SUCCESS) goto error_close_coclass_key; } if (list->viprogid) { - res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->viprogid); + res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; if (res != ERROR_SUCCESS) goto error_close_coclass_key; } } @@ -440,70 +441,6 @@ error_close_progid_key: return res; } -/*********************************************************************** - * recursive_delete_key - */ -static LONG recursive_delete_key(HKEY key) -{ - LONG res; - WCHAR subkey_name[MAX_PATH]; - DWORD cName; - HKEY subkey; - - for (;;) { - cName = sizeof(subkey_name) / sizeof(WCHAR); - res = RegEnumKeyExW(key, 0, subkey_name, &cName, - NULL, NULL, NULL, NULL); - if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) { - res = ERROR_SUCCESS; /* presumably we're done enumerating */ - break; - } - res = RegOpenKeyExW(key, subkey_name, 0, - KEY_READ | KEY_WRITE, &subkey); - if (res == ERROR_FILE_NOT_FOUND) continue; - if (res != ERROR_SUCCESS) break; - - res = recursive_delete_key(subkey); - RegCloseKey(subkey); - if (res != ERROR_SUCCESS) break; - } - - if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0); - return res; -} - -/*********************************************************************** - * recursive_delete_keyA - */ -static LONG recursive_delete_keyA(HKEY base, char const *name) -{ - LONG res; - HKEY key; - - res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key); - if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS; - if (res != ERROR_SUCCESS) return res; - res = recursive_delete_key(key); - RegCloseKey(key); - return res; -} - -/*********************************************************************** - * recursive_delete_keyW - */ -static LONG recursive_delete_keyW(HKEY base, WCHAR const *name) -{ - LONG res; - HKEY key; - - res = RegOpenKeyExW(base, name, 0, KEY_READ | KEY_WRITE, &key); - if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS; - if (res != ERROR_SUCCESS) return res; - res = recursive_delete_key(key); - RegCloseKey(key); - return res; -} - /*********************************************************************** * coclass list */ @@ -613,7 +550,7 @@ static HRESULT register_inf(BOOL doregister) INF_SET_CLSID(MkProtocol); for(i = 0; i < sizeof(pse)/sizeof(pse[0]); i++) { - pse[i].pszValue = HeapAlloc(GetProcessHeap(), 0, 39); + pse[i].pszValue = urlmon_alloc(39); sprintf(pse[i].pszValue, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", clsids[i]->Data1, clsids[i]->Data2, clsids[i]->Data3, clsids[i]->Data4[0], clsids[i]->Data4[1], clsids[i]->Data4[2], clsids[i]->Data4[3], clsids[i]->Data4[4], @@ -629,7 +566,7 @@ static HRESULT register_inf(BOOL doregister) hres = pRegInstall(URLMON_hInstance, doregister ? "RegisterDll" : "UnregisterDll", &strtable); for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++) - HeapFree(GetProcessHeap(), 0, pse[i].pszValue); + urlmon_free(pse[i].pszValue); return hres; } diff --git a/reactos/dll/win32/urlmon/sec_mgr.c b/reactos/dll/win32/urlmon/sec_mgr.c index 615d5dfd3e1..abd25473b5e 100644 --- a/reactos/dll/win32/urlmon/sec_mgr.c +++ b/reactos/dll/win32/urlmon/sec_mgr.c @@ -173,7 +173,7 @@ static ULONG WINAPI SecManagerImpl_Release(IInternetSecurityManager* iface) if(This->custom_manager) IInternetSecurityManager_Release(This->custom_manager); - HeapFree(GetProcessHeap(),0,This); + urlmon_free(This); URLMON_UnlockModule(); } @@ -251,14 +251,16 @@ static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *ifac return hres; } - if(!pwszUrl) + if(!pwszUrl) { + *pdwZone = -1; return E_INVALIDARG; + } if(dwFlags) FIXME("not supported flags: %08x\n", dwFlags); size = (strlenW(pwszUrl)+16) * sizeof(WCHAR); - url = HeapAlloc(GetProcessHeap(), 0, size); + url = urlmon_alloc(size); hres = CoInternetParseUrl(pwszUrl, PARSE_SECURITY_URL, 0, url, size/sizeof(WCHAR), &size, 0); if(FAILED(hres)) @@ -266,12 +268,12 @@ static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *ifac hres = map_url_to_zone(url, pdwZone); - HeapFree(GetProcessHeap(), 0, url); + urlmon_free(url); return hres; } -static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *iface, +static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *iface, LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) { SecManagerImpl *This = SECMGR_THIS(iface); @@ -298,7 +300,7 @@ static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *ifa FIXME("dwReserved is not supported\n"); len = strlenW(pwszUrl)+1; - buf = HeapAlloc(GetProcessHeap(), 0, (len+16)*sizeof(WCHAR)); + buf = urlmon_alloc((len+16)*sizeof(WCHAR)); hres = CoInternetParseUrl(pwszUrl, PARSE_SECURITY_URL, 0, buf, len, &size, 0); if(FAILED(hres)) @@ -306,7 +308,7 @@ static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *ifa hres = map_url_to_zone(buf, &zone); if(FAILED(hres)) { - HeapFree(GetProcessHeap(), 0, buf); + urlmon_free(buf); return hres == 0x80041001 ? E_INVALIDARG : hres; } @@ -316,6 +318,8 @@ static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *ifa static const BYTE secidFile[] = {'f','i','l','e',':'}; + urlmon_free(buf); + if(*pcbSecurityId < sizeof(secidFile)+sizeof(zone)) return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); @@ -339,11 +343,13 @@ static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *ifa len = WideCharToMultiByte(CP_ACP, 0, buf, -1, NULL, 0, NULL, NULL)-1; - if(len+sizeof(DWORD) > *pcbSecurityId) + if(len+sizeof(DWORD) > *pcbSecurityId) { + urlmon_free(buf); return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + } WideCharToMultiByte(CP_ACP, 0, buf, -1, (LPSTR)pbSecurityId, -1, NULL, NULL); - HeapFree(GetProcessHeap(), 0, buf); + urlmon_free(buf); *(DWORD*)(pbSecurityId+len) = zone; @@ -375,7 +381,7 @@ static HRESULT WINAPI SecManagerImpl_ProcessUrlAction(IInternetSecurityManager * FIXME("Default action is not implemented\n"); return E_NOTIMPL; } - + static HRESULT WINAPI SecManagerImpl_QueryCustomPolicy(IInternetSecurityManager *iface, LPCWSTR pwszUrl, REFGUID guidKey, @@ -458,7 +464,7 @@ HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) SecManagerImpl *This; TRACE("(%p,%p)\n",pUnkOuter,ppobj); - This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + This = urlmon_alloc(sizeof(*This)); /* Initialize the virtual function table. */ This->lpInternetSecurityManagerVtbl = &VT_SecManagerImpl; @@ -571,10 +577,10 @@ static ULONG WINAPI ZoneMgrImpl_Release(IInternetZoneManager* iface) TRACE("(%p)->(ref before=%u)\n",This, refCount + 1); if(!refCount) { - HeapFree(GetProcessHeap(), 0, This); + urlmon_free(This); URLMON_UnlockModule(); } - + return refCount; } @@ -784,7 +790,7 @@ static const IInternetZoneManagerVtbl ZoneMgrImplVtbl = { HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) { - ZoneMgrImpl* ret = HeapAlloc(GetProcessHeap(), 0, sizeof(ZoneMgrImpl)); + ZoneMgrImpl* ret = urlmon_alloc(sizeof(ZoneMgrImpl)); TRACE("(%p %p)\n", pUnkOuter, ppobj); ret->lpVtbl = &ZoneMgrImplVtbl; diff --git a/reactos/dll/win32/urlmon/session.c b/reactos/dll/win32/urlmon/session.c index 06c10b6d5c2..1532a4f4672 100644 --- a/reactos/dll/win32/urlmon/session.c +++ b/reactos/dll/win32/urlmon/session.c @@ -68,17 +68,17 @@ static HRESULT get_protocol_cf(LPCWSTR schema, DWORD schema_len, CLSID *pclsid, {'P','R','O','T','O','C','O','L','S','\\','H','a','n','d','l','e','r','\\'}; static const WCHAR wszCLSID[] = {'C','L','S','I','D',0}; - wszKey = HeapAlloc(GetProcessHeap(), 0, sizeof(wszProtocolsKey)+(schema_len+1)*sizeof(WCHAR)); + wszKey = urlmon_alloc(sizeof(wszProtocolsKey)+(schema_len+1)*sizeof(WCHAR)); memcpy(wszKey, wszProtocolsKey, sizeof(wszProtocolsKey)); memcpy(wszKey + sizeof(wszProtocolsKey)/sizeof(WCHAR), schema, (schema_len+1)*sizeof(WCHAR)); res = RegOpenKeyW(HKEY_CLASSES_ROOT, wszKey, &hkey); - HeapFree(GetProcessHeap(), 0, wszKey); + urlmon_free(wszKey); if(res != ERROR_SUCCESS) { TRACE("Could not open protocol handler key\n"); return E_FAIL; } - + size = sizeof(str_clsid); res = RegQueryValueExW(hkey, wszCLSID, NULL, &type, (LPBYTE)str_clsid, &size); RegCloseKey(hkey); @@ -207,10 +207,10 @@ static HRESULT WINAPI InternetSession_RegisterNameSpace(IInternetSession *iface, if(!pCF || !pwzProtocol) return E_INVALIDARG; - new_name_space = HeapAlloc(GetProcessHeap(), 0, sizeof(name_space)); + new_name_space = urlmon_alloc(sizeof(name_space)); size = (strlenW(pwzProtocol)+1)*sizeof(WCHAR); - new_name_space->protocol = HeapAlloc(GetProcessHeap(), 0, size); + new_name_space->protocol = urlmon_alloc(size); memcpy(new_name_space->protocol, pwzProtocol, size); IClassFactory_AddRef(pCF); @@ -247,8 +247,8 @@ static HRESULT WINAPI InternetSession_UnregisterNameSpace(IInternetSession *ifac name_space_list = iter->next; IClassFactory_Release(iter->cf); - HeapFree(GetProcessHeap(), 0, iter->protocol); - HeapFree(GetProcessHeap(), 0, iter); + urlmon_free(iter->protocol); + urlmon_free(iter); return S_OK; } @@ -340,7 +340,7 @@ static BOOL get_url_encoding(HKEY root, DWORD *encoding) DWORD size = sizeof(DWORD), res, type; HKEY hkey; - static const WCHAR wszKeyName[] = + static const WCHAR wszKeyName[] = {'S','O','F','T','W','A','R','E', '\\','M','i','c','r','o','s','o','f','t', '\\','W','i','n','d','o','w','s', diff --git a/reactos/dll/win32/urlmon/umon.c b/reactos/dll/win32/urlmon/umon.c index a2a7bcc9537..7022be6726d 100644 --- a/reactos/dll/win32/urlmon/umon.c +++ b/reactos/dll/win32/urlmon/umon.c @@ -101,7 +101,7 @@ static ULONG WINAPI Binding_Release(IBinding* iface) TRACE("(%p) ref=%d\n",This, ref); if(!ref) { - HeapFree(GetProcessHeap(), 0, This->URLName); + urlmon_free(This->URLName); if (This->hCacheFile) CloseHandle(This->hCacheFile); if (This->pstrCache) @@ -112,7 +112,7 @@ static ULONG WINAPI Binding_Release(IBinding* iface) if (This->pbscb) IBindStatusCallback_Release(This->pbscb); - HeapFree(GetProcessHeap(), 0, This); + urlmon_free(This); URLMON_UnlockModule(); } @@ -183,7 +183,7 @@ static void Binding_CloseCacheDownload(Binding *This) This->pstrCache = 0; } -static HRESULT Binding_MoreCacheData(Binding *This, char *buf, DWORD dwBytes) +static HRESULT Binding_MoreCacheData(Binding *This, const char *buf, DWORD dwBytes) { DWORD written; @@ -356,8 +356,8 @@ static ULONG WINAPI URLMonikerImpl_Release(IMoniker* iface) /* destroy the object if there's no more reference on it */ if (!refCount) { - HeapFree(GetProcessHeap(),0,This->URLName); - HeapFree(GetProcessHeap(),0,This); + urlmon_free(This->URLName); + urlmon_free(This); URLMON_UnlockModule(); } @@ -408,7 +408,7 @@ static HRESULT WINAPI URLMonikerImpl_IsDirty(IMoniker* iface) static HRESULT WINAPI URLMonikerImpl_Load(IMoniker* iface,IStream* pStm) { URLMonikerImpl *This = (URLMonikerImpl *)iface; - + HRESULT res; ULONG size; ULONG got; @@ -420,8 +420,8 @@ static HRESULT WINAPI URLMonikerImpl_Load(IMoniker* iface,IStream* pStm) res = IStream_Read(pStm, &size, sizeof(ULONG), &got); if(SUCCEEDED(res)) { if(got == sizeof(ULONG)) { - HeapFree(GetProcessHeap(), 0, This->URLName); - This->URLName=HeapAlloc(GetProcessHeap(),0,size); + urlmon_free(This->URLName); + This->URLName = urlmon_alloc(size); if(!This->URLName) res = E_OUTOFMEMORY; else { @@ -500,7 +500,6 @@ static HRESULT WINAPI URLMonikerImpl_BindToObject(IMoniker* iface, ******************************************************************************/ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, IBindCtx* pbc, - IMoniker* pmkToLeft, REFIID riid, VOID** ppvObject) { @@ -511,25 +510,20 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, Binding *bind; int len; - WARN("(%s %p %p %s %p)\n", debugstr_w(URLName), pbc, pmkToLeft, debugstr_guid(riid), - ppvObject); + WARN("(%s %p %s %p)\n", debugstr_w(URLName), pbc, debugstr_guid(riid), ppvObject); - if(pmkToLeft) { - FIXME("pmkToLeft != NULL\n"); - return E_NOTIMPL; - } if(!IsEqualIID(&IID_IStream, riid)) { FIXME("unsupported iid\n"); return E_NOTIMPL; } - bind = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Binding)); + bind = urlmon_alloc_zero(sizeof(Binding)); bind->lpVtbl = &BindingVtbl; bind->ref = 1; URLMON_LockModule(); len = lstrlenW(URLName)+1; - bind->URLName = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + bind->URLName = urlmon_alloc(len*sizeof(WCHAR)); memcpy(bind->URLName, URLName, len*sizeof(WCHAR)); hres = UMCreateStreamOnCacheFile(bind->URLName, 0, szFileName, &bind->hCacheFile, &bind->pstrCache); @@ -567,15 +561,15 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, url.dwStructSize = sizeof(url); url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = url.dwUserNameLength = url.dwPasswordLength = 1; InternetCrackUrlW(URLName, 0, ICU_ESCAPE, &url); - host = HeapAlloc(GetProcessHeap(), 0, (url.dwHostNameLength + 1) * sizeof(WCHAR)); + host = urlmon_alloc((url.dwHostNameLength + 1) * sizeof(WCHAR)); memcpy(host, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR)); host[url.dwHostNameLength] = '\0'; - path = HeapAlloc(GetProcessHeap(), 0, (url.dwUrlPathLength + 1) * sizeof(WCHAR)); + path = urlmon_alloc((url.dwUrlPathLength + 1) * sizeof(WCHAR)); memcpy(path, url.lpszUrlPath, url.dwUrlPathLength * sizeof(WCHAR)); path[url.dwUrlPathLength] = '\0'; if (url.dwUserNameLength) { - user = HeapAlloc(GetProcessHeap(), 0, ((url.dwUserNameLength + 1) * sizeof(WCHAR))); + user = urlmon_alloc(((url.dwUserNameLength + 1) * sizeof(WCHAR))); memcpy(user, url.lpszUserName, url.dwUserNameLength * sizeof(WCHAR)); user[url.dwUserNameLength] = 0; } @@ -585,7 +579,7 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, } if (url.dwPasswordLength) { - pass = HeapAlloc(GetProcessHeap(), 0, ((url.dwPasswordLength + 1) * sizeof(WCHAR))); + pass = urlmon_alloc(((url.dwPasswordLength + 1) * sizeof(WCHAR))); memcpy(pass, url.lpszPassword, url.dwPasswordLength * sizeof(WCHAR)); pass[url.dwPasswordLength] = 0; } @@ -610,19 +604,13 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, url.nPort = INTERNET_DEFAULT_FTP_PORT; dwService = INTERNET_SERVICE_FTP; break; - + case INTERNET_SCHEME_GOPHER: if (!url.nPort) url.nPort = INTERNET_DEFAULT_GOPHER_PORT; dwService = INTERNET_SERVICE_GOPHER; break; - case INTERNET_SCHEME_HTTP: - if (!url.nPort) - url.nPort = INTERNET_DEFAULT_HTTP_PORT; - dwService = INTERNET_SERVICE_HTTP; - break; - case INTERNET_SCHEME_HTTPS: if (!url.nPort) url.nPort = INTERNET_DEFAULT_HTTPS_PORT; @@ -715,7 +703,7 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, InternetCloseHandle(bind->hrequest); hres = S_OK; } - + InternetCloseHandle(bind->hconnect); InternetCloseHandle(bind->hinternet); } while(0); @@ -723,10 +711,10 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, Binding_FinishedDownload(bind, hres); Binding_CloseCacheDownload(bind); - HeapFree(GetProcessHeap(), 0, user); - HeapFree(GetProcessHeap(), 0, pass); - HeapFree(GetProcessHeap(), 0, path); - HeapFree(GetProcessHeap(), 0, host); + urlmon_free(user); + urlmon_free(pass); + urlmon_free(path); + urlmon_free(host); } } } @@ -749,17 +737,19 @@ static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface, URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW), schema, sizeof(schema)/sizeof(WCHAR), 0, NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0}; + if(pmkToLeft) + FIXME("Unsupported pmkToLeft\n"); + bret = InternetCrackUrlW(This->URLName, 0, ICU_ESCAPE, &url); if(!bret) { ERR("InternetCrackUrl failed: %u\n", GetLastError()); return E_FAIL; } - if(url.nScheme == INTERNET_SCHEME_HTTP - || url.nScheme== INTERNET_SCHEME_HTTPS + if(url.nScheme== INTERNET_SCHEME_HTTPS || url.nScheme== INTERNET_SCHEME_FTP || url.nScheme == INTERNET_SCHEME_GOPHER) - return URLMonikerImpl_BindToStorage_hack(This->URLName, pbc, pmkToLeft, riid, ppvObject); + return URLMonikerImpl_BindToStorage_hack(This->URLName, pbc, riid, ppvObject); TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObject); @@ -776,7 +766,7 @@ static HRESULT WINAPI URLMonikerImpl_Reduce(IMoniker* iface, IMoniker** ppmkReduced) { URLMonikerImpl *This = (URLMonikerImpl *)iface; - + TRACE("(%p,%p,%d,%p,%p)\n",This,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced); if(!ppmkReduced) @@ -860,7 +850,7 @@ static HRESULT WINAPI URLMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherM static HRESULT WINAPI URLMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash) { URLMonikerImpl *This = (URLMonikerImpl *)iface; - + int h = 0,i,skip,len; int off = 0; LPOLESTR val; @@ -959,14 +949,14 @@ static HRESULT WINAPI URLMonikerImpl_GetDisplayName(IMoniker* iface, LPOLESTR *ppszDisplayName) { URLMonikerImpl *This = (URLMonikerImpl *)iface; - + int len; - + TRACE("(%p,%p,%p,%p)\n",This,pbc,pmkToLeft,ppszDisplayName); - + if(!ppszDisplayName) return E_INVALIDARG; - + /* FIXME: If this is a partial URL, try and get a URL moniker from SZ_URLCONTEXT in the bind context, then look at pmkToLeft to try and complete the URL */ @@ -1052,7 +1042,7 @@ static HRESULT URLMonikerImpl_Construct(URLMonikerImpl* This, LPCOLESTR lpszLeft This->lpvtbl = &VT_URLMonikerImpl; This->ref = 0; - This->URLName = HeapAlloc(GetProcessHeap(), 0, INTERNET_MAX_URL_LENGTH*sizeof(WCHAR)); + This->URLName = urlmon_alloc(INTERNET_MAX_URL_LENGTH*sizeof(WCHAR)); if(lpszLeftURLName) hres = CoInternetCombineUrl(lpszLeftURLName, lpszURLName, URL_FILE_USE_PATHURL, @@ -1062,78 +1052,20 @@ static HRESULT URLMonikerImpl_Construct(URLMonikerImpl* This, LPCOLESTR lpszLeft This->URLName, INTERNET_MAX_URL_LENGTH, &sizeStr, 0); if(FAILED(hres)) { - HeapFree(GetProcessHeap(), 0, This->URLName); + urlmon_free(This->URLName); return hres; } URLMON_LockModule(); if(sizeStr != INTERNET_MAX_URL_LENGTH) - This->URLName = HeapReAlloc(GetProcessHeap(), 0, This->URLName, (sizeStr+1)*sizeof(WCHAR)); + This->URLName = urlmon_realloc(This->URLName, (sizeStr+1)*sizeof(WCHAR)); TRACE("URLName = %s\n", debugstr_w(This->URLName)); return S_OK; } -/*********************************************************************** - * CreateAsyncBindCtx (URLMON.@) - */ -HRESULT WINAPI CreateAsyncBindCtx(DWORD reserved, IBindStatusCallback *callback, - IEnumFORMATETC *format, IBindCtx **pbind) -{ - TRACE("(%08x %p %p %p)\n", reserved, callback, format, pbind); - - if(!callback) - return E_INVALIDARG; - - return CreateAsyncBindCtxEx(NULL, 0, callback, format, pbind, 0); -} -/*********************************************************************** - * CreateAsyncBindCtxEx (URLMON.@) - * - * Create an asynchronous bind context. - */ -HRESULT WINAPI CreateAsyncBindCtxEx(IBindCtx *ibind, DWORD options, - IBindStatusCallback *callback, IEnumFORMATETC *format, IBindCtx** pbind, - DWORD reserved) -{ - HRESULT hres; - BIND_OPTS bindopts; - IBindCtx *bctx; - - TRACE("(%p %08x %p %p %p %d)\n", ibind, options, callback, format, pbind, reserved); - - if(!pbind) - return E_INVALIDARG; - - if(options) - FIXME("not supported options %08x\n", options); - if(format) - FIXME("format is not supported\n"); - - if(reserved) - WARN("reserved=%d\n", reserved); - - hres = CreateBindCtx(0, &bctx); - if(FAILED(hres)) - return hres; - - bindopts.cbStruct = sizeof(BIND_OPTS); - bindopts.grfFlags = BIND_MAYBOTHERUSER; - bindopts.grfMode = STGM_READWRITE | STGM_SHARE_EXCLUSIVE; - bindopts.dwTickCountDeadline = 0; - IBindCtx_SetBindOptions(bctx, &bindopts); - - if(callback) - RegisterBindStatusCallback(bctx, callback, NULL, 0); - - *pbind = bctx; - - return S_OK; -} - - /*********************************************************************** * CreateURLMonikerEx (URLMON.@) * @@ -1160,7 +1092,7 @@ HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker if (dwFlags & URL_MK_UNIFORM) FIXME("ignoring flag URL_MK_UNIFORM\n"); - if(!(obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj)))) + if(!(obj = urlmon_alloc(sizeof(*obj)))) return E_OUTOFMEMORY; if(pmkContext) { @@ -1173,13 +1105,13 @@ HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker IBindCtx_Release(bind); } } - + hres = URLMonikerImpl_Construct(obj, lefturl, szURL); CoTaskMemFree(lefturl); if(SUCCEEDED(hres)) hres = URLMonikerImpl_QueryInterface((IMoniker*)obj, &IID_IMoniker, (void**)ppmk); else - HeapFree(GetProcessHeap(), 0, obj); + urlmon_free(obj); return hres; } @@ -1229,7 +1161,7 @@ HRESULT WINAPI CoInternetQueryInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption, HRESULT WINAPI IsAsyncMoniker(IMoniker *pmk) { IUnknown *am; - + TRACE("(%p)\n", pmk); if(!pmk) return E_INVALIDARG; @@ -1276,85 +1208,6 @@ HRESULT WINAPI BindAsyncMoniker(IMoniker *pmk, DWORD grfOpt, IBindStatusCallback return hr; } -/*********************************************************************** - * 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) -{ - IBindStatusCallback *prev; - - TRACE("(%p,%p,%p,%u)\n", pbc, pbsc, ppbscPrevious, dwReserved); - - if (pbc == NULL || pbsc == NULL) - return E_INVALIDARG; - - if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown **)&prev))) - { - IBindCtx_RevokeObjectParam(pbc, BSCBHolder); - if (ppbscPrevious) - *ppbscPrevious = prev; - else - IBindStatusCallback_Release(prev); - } - - return IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown *)pbsc); -} - -/*********************************************************************** - * 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, or - * E_FAIL if pbsc wasn't registered with pbc. - */ -HRESULT WINAPI RevokeBindStatusCallback( - IBindCtx *pbc, - IBindStatusCallback *pbsc) -{ - IBindStatusCallback *callback; - HRESULT hr = E_FAIL; - - TRACE("(%p,%p)\n", pbc, pbsc); - - if (pbc == NULL || pbsc == NULL) - return E_INVALIDARG; - - if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown **)&callback))) - { - if (callback == pbsc) - { - IBindCtx_RevokeObjectParam(pbc, BSCBHolder); - hr = S_OK; - } - IBindStatusCallback_Release(pbsc); - } - - return hr; -} - /*********************************************************************** * URLDownloadToFileA (URLMON.@) * @@ -1384,20 +1237,20 @@ HRESULT WINAPI URLDownloadToFileA(LPUNKNOWN pCaller, FIXME("(%p,%s,%s,%08x,%p) cannot accept NULL strings !\n", pCaller, debugstr_a(szURL), debugstr_a(szFileName), dwReserved, lpfnCB); return E_INVALIDARG; /* The error code is not specified in this case... */ } - + if (RtlCreateUnicodeStringFromAsciiz(&szURL_w, szURL)) { if (RtlCreateUnicodeStringFromAsciiz(&szFileName_w, szFileName)) { HRESULT ret = URLDownloadToFileW(pCaller, szURL_w.Buffer, szFileName_w.Buffer, dwReserved, lpfnCB); RtlFreeUnicodeString(&szURL_w); RtlFreeUnicodeString(&szFileName_w); - + return ret; } else { RtlFreeUnicodeString(&szURL_w); } } - + FIXME("(%p,%s,%s,%08x,%p) could not allocate W strings !\n", pCaller, szURL, szFileName, dwReserved, lpfnCB); return E_OUTOFMEMORY; } @@ -1447,7 +1300,7 @@ HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, hinternet = InternetOpenW(wszAppName, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hinternet == NULL) { return E_OUTOFMEMORY; - } + } memset(&url, 0, sizeof(url)); url.dwStructSize = sizeof(url); @@ -1467,7 +1320,7 @@ HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, return S_OK; } } - + hcon = InternetConnectW(hinternet, url.lpszHostName, url.nPort, url.lpszUserName, url.lpszPassword, INTERNET_SERVICE_HTTP, 0, 0); @@ -1475,13 +1328,13 @@ HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, InternetCloseHandle(hinternet); return E_OUTOFMEMORY; } - + hreq = HttpOpenRequestW(hcon, NULL, url.lpszUrlPath, NULL, NULL, NULL, 0, 0); if (!hreq) { InternetCloseHandle(hinternet); InternetCloseHandle(hcon); return E_OUTOFMEMORY; - } + } if (!HttpSendRequestW(hreq, NULL, 0, NULL, 0)) { InternetCloseHandle(hinternet); @@ -1489,18 +1342,18 @@ HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, InternetCloseHandle(hreq); return E_OUTOFMEMORY; } - + if (HttpQueryInfoW(hreq, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &total_size, &arg_size, NULL)) { TRACE(" total size : %d\n", total_size); } - + hfile = CreateFileW(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (hfile == INVALID_HANDLE_VALUE) { return E_ACCESSDENIED; } - + if (lpfnCB) { if (IBindStatusCallback_OnProgress(lpfnCB, 0, total_size != 0xFFFFFFFF ? total_size : 0, BINDSTATUS_BEGINDOWNLOADDATA, szURL) == E_ABORT) { @@ -1511,7 +1364,7 @@ HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, return S_OK; } } - + total = 0; while (1) { r = InternetReadFile(hreq, buffer, sizeof(buffer), &sz); @@ -1519,13 +1372,13 @@ HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, InternetCloseHandle(hreq); InternetCloseHandle(hcon); InternetCloseHandle(hinternet); - + CloseHandle(hfile); - return E_OUTOFMEMORY; + return E_OUTOFMEMORY; } if (!sz) break; - + total += sz; if (lpfnCB) { @@ -1538,12 +1391,12 @@ HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, return S_OK; } } - + if (!WriteFile(hfile, buffer, sz, &written, NULL)) { InternetCloseHandle(hreq); InternetCloseHandle(hcon); InternetCloseHandle(hinternet); - + CloseHandle(hfile); return E_OUTOFMEMORY; } @@ -1559,11 +1412,11 @@ HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, return S_OK; } } - + InternetCloseHandle(hreq); InternetCloseHandle(hcon); InternetCloseHandle(hinternet); - + CloseHandle(hfile); return S_OK; @@ -1584,12 +1437,12 @@ HRESULT WINAPI URLDownloadToCacheFileA(LPUNKNOWN lpUnkCaller, LPCSTR szURL, LPST if(szURL) { len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0); - url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + url = urlmon_alloc(len*sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, szURL, -1, url, -1); } if(szFileName) - file_name = HeapAlloc(GetProcessHeap(), 0, dwBufLength*sizeof(WCHAR)); + file_name = urlmon_alloc(dwBufLength*sizeof(WCHAR)); hres = URLDownloadToCacheFileW(lpUnkCaller, url, file_name, dwBufLength*sizeof(WCHAR), dwReserved, pBSC); @@ -1597,8 +1450,8 @@ HRESULT WINAPI URLDownloadToCacheFileA(LPUNKNOWN lpUnkCaller, LPCSTR szURL, LPST if(SUCCEEDED(hres) && file_name) WideCharToMultiByte(CP_ACP, 0, file_name, -1, szFileName, dwBufLength, NULL, NULL); - HeapFree(GetProcessHeap(), 0, url); - HeapFree(GetProcessHeap(), 0, file_name); + urlmon_free(url); + urlmon_free(file_name); return hres; } @@ -1668,7 +1521,7 @@ HRESULT WINAPI HlinkSimpleNavigateToString( LPCWSTR szTarget, HRESULT WINAPI HlinkNavigateString( IUnknown *pUnk, LPCWSTR szTarget ) { TRACE("%p %s\n", pUnk, debugstr_w( szTarget ) ); - return HlinkSimpleNavigateToString( + return HlinkSimpleNavigateToString( szTarget, NULL, NULL, pUnk, NULL, NULL, 0, 0 ); } diff --git a/reactos/dll/win32/urlmon/umstream.c b/reactos/dll/win32/urlmon/umstream.c index e7827c49dd1..eeb1570549b 100644 --- a/reactos/dll/win32/urlmon/umstream.c +++ b/reactos/dll/win32/urlmon/umstream.c @@ -54,7 +54,7 @@ HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL, HRESULT hr; size = (strlenW(pszURL)+1)*sizeof(WCHAR); - url = HeapAlloc(GetProcessHeap(), 0, size); + url = urlmon_alloc(size); memcpy(url, pszURL, size); for (c = url; *c && *c != '#' && *c != '?'; ++c) @@ -72,7 +72,7 @@ HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL, else hr = 0; - HeapFree(GetProcessHeap(), 0, url); + urlmon_free(url); if (hr) return hr; @@ -99,17 +99,13 @@ HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL, } } - ucstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,sizeof(IUMCacheStream)); - if(ucstr ) + ucstr = urlmon_alloc_zero(sizeof(IUMCacheStream)); + if(ucstr) { - ucstr->pszURL = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - sizeof(WCHAR) * (lstrlenW(pszURL) + 1)); + ucstr->pszURL = urlmon_alloc_zero(sizeof(WCHAR) * (lstrlenW(pszURL) + 1)); if (ucstr->pszURL) { - ucstr->pszFileName = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - sizeof(WCHAR) * (lstrlenW(pszFileName) + 1)); + ucstr->pszFileName = urlmon_alloc_zero(sizeof(WCHAR) * (lstrlenW(pszFileName) + 1)); if (ucstr->pszFileName) { ucstr->lpVtbl=&stvt; @@ -123,9 +119,9 @@ HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL, return S_OK; } - HeapFree(GetProcessHeap(), 0, ucstr->pszURL); + urlmon_free(ucstr->pszURL); } - HeapFree(GetProcessHeap(), 0, ucstr); + urlmon_free(ucstr); } CloseHandle(handle); if (phfile) @@ -211,14 +207,14 @@ static ULONG WINAPI IStream_fnRelease(IStream *iface) TRACE(" destroying UMCacheStream (%p)\n",This); UMCloseCacheFileStream(This); CloseHandle(This->handle); - HeapFree(GetProcessHeap(), 0, This->pszFileName); - HeapFree(GetProcessHeap(), 0, This->pszURL); - HeapFree(GetProcessHeap(),0,This); + urlmon_free(This->pszFileName); + urlmon_free(This->pszURL); + urlmon_free(This); } return refCount; } -static HRESULT WINAPI IStream_fnRead (IStream * iface, +static HRESULT WINAPI IStream_fnRead (IStream * iface, void* pv, ULONG cb, ULONG* pcbRead) @@ -378,3 +374,309 @@ static const IStreamVtbl stvt = IStream_fnClone }; + +typedef struct ProxyBindStatusCallback +{ + const IBindStatusCallbackVtbl *lpVtbl; + + IBindStatusCallback *pBSC; +} ProxyBindStatusCallback; + +static HRESULT WINAPI ProxyBindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv) +{ + if (IsEqualGUID(&IID_IBindStatusCallback, riid) || + IsEqualGUID(&IID_IUnknown, riid)) + { + *ppv = iface; + IUnknown_AddRef(iface); + return S_OK; + } + + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI ProxyBindStatusCallback_AddRef(IBindStatusCallback *iface) +{ + return 2; +} + +static ULONG WINAPI ProxyBindStatusCallback_Release(IBindStatusCallback *iface) +{ + return 1; +} + +static HRESULT WINAPI ProxyBindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved, + IBinding *pib) +{ + ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface; + + if(This->pBSC) + return IBindStatusCallback_OnStartBinding(This->pBSC, dwReserved, pib); + + return S_OK; +} + +static HRESULT WINAPI ProxyBindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority) +{ + ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface; + + if(This->pBSC) + return IBindStatusCallback_GetPriority(This->pBSC, pnPriority); + + return S_OK; +} + +static HRESULT WINAPI ProxyBindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved) +{ + ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface; + + if(This->pBSC) + return IBindStatusCallback_OnLowResource(This->pBSC, reserved); + + return S_OK; +} + +static HRESULT WINAPI ProxyBindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress, + ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText) +{ + ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface; + + if(This->pBSC) + return IBindStatusCallback_OnProgress(This->pBSC, ulProgress, + ulProgressMax, ulStatusCode, + szStatusText); + + return S_OK; +} + +static HRESULT WINAPI ProxyBindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError) +{ + ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface; + + if(This->pBSC) + return IBindStatusCallback_OnStopBinding(This->pBSC, hresult, szError); + + return S_OK; +} + +static HRESULT WINAPI ProxyBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo) +{ + ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface; + + if(This->pBSC) + return IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo); + + return E_INVALIDARG; +} + +static HRESULT WINAPI ProxyBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF, + DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed) +{ + ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface; + + if(This->pBSC) + return IBindStatusCallback_OnDataAvailable(This->pBSC, grfBSCF, dwSize, + pformatetc, pstgmed); + + return S_OK; +} + +static HRESULT WINAPI ProxyBindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk) +{ + ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface; + + if(This->pBSC) + return IBindStatusCallback_OnObjectAvailable(This->pBSC, riid, punk); + + return S_OK; +} + +static HRESULT WINAPI BlockingBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF, + DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed) +{ + return S_OK; +} + +static const IBindStatusCallbackVtbl BlockingBindStatusCallbackVtbl = +{ + ProxyBindStatusCallback_QueryInterface, + ProxyBindStatusCallback_AddRef, + ProxyBindStatusCallback_Release, + ProxyBindStatusCallback_OnStartBinding, + ProxyBindStatusCallback_GetPriority, + ProxyBindStatusCallback_OnLowResource, + ProxyBindStatusCallback_OnProgress, + ProxyBindStatusCallback_OnStopBinding, + ProxyBindStatusCallback_GetBindInfo, + BlockingBindStatusCallback_OnDataAvailable, + ProxyBindStatusCallback_OnObjectAvailable +}; + +static HRESULT WINAPI AsyncBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo) +{ + ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface; + HRESULT hr = IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo); + *grfBINDF |= BINDF_PULLDATA | BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE; + return hr; +} + +static const IBindStatusCallbackVtbl AsyncBindStatusCallbackVtbl = +{ + ProxyBindStatusCallback_QueryInterface, + ProxyBindStatusCallback_AddRef, + ProxyBindStatusCallback_Release, + ProxyBindStatusCallback_OnStartBinding, + ProxyBindStatusCallback_GetPriority, + ProxyBindStatusCallback_OnLowResource, + ProxyBindStatusCallback_OnProgress, + ProxyBindStatusCallback_OnStopBinding, + AsyncBindStatusCallback_GetBindInfo, + ProxyBindStatusCallback_OnDataAvailable, + ProxyBindStatusCallback_OnObjectAvailable +}; + +static HRESULT URLStartDownload(LPCWSTR szURL, LPSTREAM *ppStream, IBindStatusCallback *pBSC) +{ + HRESULT hr; + IMoniker *pMoniker; + IBindCtx *pbc; + + *ppStream = NULL; + + hr = CreateURLMoniker(NULL, szURL, &pMoniker); + if (FAILED(hr)) + return hr; + + hr = CreateBindCtx(0, &pbc); + if (FAILED(hr)) + { + IMoniker_Release(pMoniker); + return hr; + } + + hr = RegisterBindStatusCallback(pbc, pBSC, NULL, 0); + if (FAILED(hr)) + { + IBindCtx_Release(pbc); + IMoniker_Release(pMoniker); + return hr; + } + + hr = IMoniker_BindToStorage(pMoniker, pbc, NULL, &IID_IStream, (void **)ppStream); + + /* BindToStorage returning E_PENDING because it's asynchronous is not an error */ + if (hr == E_PENDING) hr = S_OK; + + IBindCtx_Release(pbc); + IMoniker_Release(pMoniker); + + return hr; +} + +/*********************************************************************** + * URLOpenBlockingStreamA (URLMON.@) + */ +HRESULT WINAPI URLOpenBlockingStreamA(LPUNKNOWN pCaller, LPCSTR szURL, + LPSTREAM *ppStream, DWORD dwReserved, + LPBINDSTATUSCALLBACK lpfnCB) +{ + LPWSTR szURLW; + int len; + HRESULT hr; + + TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, szURL, ppStream, dwReserved, lpfnCB); + + if (!szURL || !ppStream) + return E_INVALIDARG; + + len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0); + szURLW = urlmon_alloc(len * sizeof(WCHAR)); + if (!szURLW) + { + *ppStream = NULL; + return E_OUTOFMEMORY; + } + MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len); + + hr = URLOpenBlockingStreamW(pCaller, szURLW, ppStream, dwReserved, lpfnCB); + + urlmon_free(szURLW); + + return hr; +} + +/*********************************************************************** + * URLOpenBlockingStreamW (URLMON.@) + */ +HRESULT WINAPI URLOpenBlockingStreamW(LPUNKNOWN pCaller, LPCWSTR szURL, + LPSTREAM *ppStream, DWORD dwReserved, + LPBINDSTATUSCALLBACK lpfnCB) +{ + ProxyBindStatusCallback blocking_bsc; + + TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, debugstr_w(szURL), ppStream, + dwReserved, lpfnCB); + + if (!szURL || !ppStream) + return E_INVALIDARG; + + blocking_bsc.lpVtbl = &BlockingBindStatusCallbackVtbl; + blocking_bsc.pBSC = lpfnCB; + + return URLStartDownload(szURL, ppStream, (IBindStatusCallback *)&blocking_bsc); +} + +/*********************************************************************** + * URLOpenStreamA (URLMON.@) + */ +HRESULT WINAPI URLOpenStreamA(LPUNKNOWN pCaller, LPCSTR szURL, DWORD dwReserved, + LPBINDSTATUSCALLBACK lpfnCB) +{ + LPWSTR szURLW; + int len; + HRESULT hr; + + TRACE("(%p, %s, 0x%x, %p)\n", pCaller, szURL, dwReserved, lpfnCB); + + if (!szURL) + return E_INVALIDARG; + + len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0); + szURLW = urlmon_alloc(len * sizeof(WCHAR)); + if (!szURLW) + return E_OUTOFMEMORY; + MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len); + + hr = URLOpenStreamW(pCaller, szURLW, dwReserved, lpfnCB); + + urlmon_free(szURLW); + + return hr; +} + +/*********************************************************************** + * URLOpenStreamW (URLMON.@) + */ +HRESULT WINAPI URLOpenStreamW(LPUNKNOWN pCaller, LPCWSTR szURL, DWORD dwReserved, + LPBINDSTATUSCALLBACK lpfnCB) +{ + HRESULT hr; + ProxyBindStatusCallback async_bsc; + IStream *pStream; + + TRACE("(%p, %s, 0x%x, %p)\n", pCaller, debugstr_w(szURL), dwReserved, + lpfnCB); + + if (!szURL) + return E_INVALIDARG; + + async_bsc.lpVtbl = &AsyncBindStatusCallbackVtbl; + async_bsc.pBSC = lpfnCB; + + hr = URLStartDownload(szURL, &pStream, (IBindStatusCallback *)&async_bsc); + if (SUCCEEDED(hr) && pStream) + IStream_Release(pStream); + + return hr; +} diff --git a/reactos/dll/win32/urlmon/urlmon.rbuild b/reactos/dll/win32/urlmon/urlmon.rbuild index 4c47a87ec86..f0d19b00d0b 100644 --- a/reactos/dll/win32/urlmon/urlmon.rbuild +++ b/reactos/dll/win32/urlmon/urlmon.rbuild @@ -1,14 +1,13 @@ + + . include/reactos/wine - - - 0x600 - 0x501 - 0x501 + 0x600 + 0x600 wine ole32 shlwapi @@ -18,6 +17,7 @@ kernel32 ntdll uuid + bindctx.c binding.c bindprot.c file.c diff --git a/reactos/dll/win32/urlmon/urlmon.spec b/reactos/dll/win32/urlmon/urlmon.spec index c72c0ebb5ef..fdb94eb0123 100644 --- a/reactos/dll/win32/urlmon/urlmon.spec +++ b/reactos/dll/win32/urlmon/urlmon.spec @@ -38,7 +38,7 @@ @ stub FindMediaType @ stub FindMediaTypeClass @ stdcall FindMimeFromData(long ptr ptr long ptr long ptr long) -@ stub GetClassFileOrMime +@ stdcall GetClassFileOrMime(ptr wstr ptr long wstr long ptr) @ stub GetClassURL @ stub GetComponentIDFromCLSSPEC @ stub GetMarkOfTheWeb @@ -70,12 +70,12 @@ @ stdcall URLDownloadToFileA(ptr str str long ptr) @ stdcall URLDownloadToFileW(ptr wstr wstr long ptr) @ stub URLDownloadW -@ stub URLOpenBlockingStreamA -@ stub URLOpenBlockingStreamW +@ stdcall URLOpenBlockingStreamA(ptr str ptr long ptr) +@ stdcall URLOpenBlockingStreamW(ptr wstr ptr long ptr) @ stub URLOpenPullStreamA @ stub URLOpenPullStreamW -@ stub URLOpenStreamA -@ stub URLOpenStreamW +@ stdcall URLOpenStreamA(ptr str long ptr) +@ stdcall URLOpenStreamW(ptr wstr long ptr) @ stub UrlMkBuildVersion @ stdcall UrlMkGetSessionOption(long ptr long ptr long) @ stdcall UrlMkSetSessionOption(long ptr long long) diff --git a/reactos/dll/win32/urlmon/urlmon_main.c b/reactos/dll/win32/urlmon/urlmon_main.c index 8b1e3fdab6f..10d3d9587d7 100644 --- a/reactos/dll/win32/urlmon/urlmon_main.c +++ b/reactos/dll/win32/urlmon/urlmon_main.c @@ -143,7 +143,7 @@ static HRESULT WINAPI CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, ClassFactory *This = (ClassFactory*)iface; HRESULT hres; LPUNKNOWN punk; - + TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); *ppobj = NULL; @@ -181,13 +181,15 @@ static const ClassFactory FtpProtocolCF = { &ClassFactoryVtbl, FtpProtocol_Construct}; static const ClassFactory HttpProtocolCF = { &ClassFactoryVtbl, HttpProtocol_Construct}; +static const ClassFactory HttpSProtocolCF = + { &ClassFactoryVtbl, HttpSProtocol_Construct}; static const ClassFactory MkProtocolCF = { &ClassFactoryVtbl, MkProtocol_Construct}; static const ClassFactory SecurityManagerCF = { &ClassFactoryVtbl, SecManagerImpl_Construct}; static const ClassFactory ZoneManagerCF = { &ClassFactoryVtbl, ZoneMgrImpl_Construct}; - + struct object_creation_info { const CLSID *clsid; @@ -198,6 +200,7 @@ struct object_creation_info static const WCHAR wszFile[] = {'f','i','l','e',0}; static const WCHAR wszFtp[] = {'f','t','p',0}; static const WCHAR wszHttp[] = {'h','t','t','p',0}; +static const WCHAR wszHttps[] = {'h','t','t','p','s',0}; static const WCHAR wszMk[] = {'m','k',0}; static const struct object_creation_info object_creation[] = @@ -205,6 +208,7 @@ static const struct object_creation_info object_creation[] = { &CLSID_FileProtocol, CLASSFACTORY(&FileProtocolCF), wszFile }, { &CLSID_FtpProtocol, CLASSFACTORY(&FtpProtocolCF), wszFtp }, { &CLSID_HttpProtocol, CLASSFACTORY(&HttpProtocolCF), wszHttp }, + { &CLSID_HttpSProtocol, CLASSFACTORY(&HttpSProtocolCF), wszHttps }, { &CLSID_MkProtocol, CLASSFACTORY(&MkProtocolCF), wszMk }, { &CLSID_InternetSecurityManager, CLASSFACTORY(&SecurityManagerCF), NULL }, { &CLSID_InternetZoneManager, CLASSFACTORY(&ZoneManagerCF), NULL } @@ -260,9 +264,9 @@ static void init_session(BOOL init) HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { int i; - + TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); - + for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) { if (IsEqualGUID(object_creation[i].clsid, rclsid)) @@ -322,7 +326,7 @@ HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPSTR pcszUAOut, DWORD *cbS /************************************************************************** * IsValidURL (URLMON.@) - * + * * Determines if a specified string is a valid URL. * * PARAMS @@ -341,10 +345,10 @@ HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPSTR pcszUAOut, DWORD *cbS HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved) { FIXME("(%p, %s, %d): stub\n", pBC, debugstr_w(szURL), dwReserved); - + if (pBC != NULL || dwReserved != 0) return E_INVALIDARG; - + return S_OK; } @@ -408,11 +412,11 @@ void WINAPI ReleaseBindInfo(BINDINFO* pbindinfo) pbindinfo->cbSize = size; } -/*********************************************************************** - * FindMimeFromData (URLMON.@) - * - * Determines the Multipurpose Internet Mail Extensions (MIME) type from the data provided. - */ +static BOOL text_richtext_filter(const BYTE *b, DWORD size) +{ + return size > 5 && !memcmp(b, "{\\rtf", 5); +} + static BOOL text_html_filter(const BYTE *b, DWORD size) { int i; @@ -432,6 +436,13 @@ static BOOL text_html_filter(const BYTE *b, DWORD size) return FALSE; } +static BOOL audio_wav_filter(const BYTE *b, DWORD size) +{ + return size > 12 + && b[0] == 'R' && b[1] == 'I' && b[2] == 'F' && b[3] == 'F' + && b[8] == 'W' && b[9] == 'A' && b[10] == 'V' && b[11] == 'E'; +} + static BOOL image_gif_filter(const BYTE *b, DWORD size) { return size >= 6 @@ -480,6 +491,11 @@ static BOOL video_mpeg_filter(const BYTE *b, DWORD size) && (b[3] == 0xb3 || b[3] == 0xba); } +static BOOL application_postscript_filter(const BYTE *b, DWORD size) +{ + return size > 2 && b[0] == '%' && b[1] == '!'; +} + static BOOL application_pdf_filter(const BYTE *b, DWORD size) { return size > 4 && b[0] == 0x25 && b[1] == 0x50 && b[2] == 0x44 && b[3] == 0x46; @@ -522,6 +538,11 @@ static BOOL application_octet_stream_filter(const BYTE *b, DWORD size) return TRUE; } +/*********************************************************************** + * FindMimeFromData (URLMON.@) + * + * Determines the Multipurpose Internet Mail Extensions (MIME) type from the data provided. + */ HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer, DWORD cbSize, LPCWSTR pwzMimeProposed, DWORD dwMimeFlags, LPWSTR* ppwzMimeOut, DWORD dwReserved) @@ -558,6 +579,8 @@ HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer, int i; static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0}; + static const WCHAR wszTextRichtext[] = {'t','e','x','t','/','r','i','c','h','t','e','x','t',0}; + static const WCHAR wszAudioWav[] = {'a','u','d','i','o','/','w','a','v',0}; static const WCHAR wszImageGif[] = {'i','m','a','g','e','/','g','i','f',0}; static const WCHAR wszImagePjpeg[] = {'i','m','a','g','e','/','p','j','p','e','g',0}; static const WCHAR wszImageTiff[] = {'i','m','a','g','e','/','t','i','f','f',0}; @@ -565,6 +588,8 @@ HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer, static const WCHAR wszImageBmp[] = {'i','m','a','g','e','/','b','m','p',0}; static const WCHAR wszVideoAvi[] = {'v','i','d','e','o','/','a','v','i',0}; static const WCHAR wszVideoMpeg[] = {'v','i','d','e','o','/','m','p','e','g',0}; + static const WCHAR wszAppPostscript[] = + {'a','p','p','l','i','c','a','t','i','o','n','/','p','o','s','t','s','c','r','i','p','t',0}; static const WCHAR wszAppPdf[] = {'a','p','p','l','i','c','a','t','i','o','n','/', 'p','d','f',0}; static const WCHAR wszAppXZip[] = {'a','p','p','l','i','c','a','t','i','o','n','/', @@ -584,6 +609,8 @@ HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer, BOOL (*filter)(const BYTE *,DWORD); } mime_filters[] = { {wszTextHtml, text_html_filter}, + {wszTextRichtext, text_richtext_filter}, + {wszAudioWav, audio_wav_filter}, {wszImageGif, image_gif_filter}, {wszImagePjpeg, image_pjpeg_filter}, {wszImageTiff, image_tiff_filter}, @@ -591,6 +618,7 @@ HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer, {wszImageBmp, image_bmp_filter}, {wszVideoAvi, video_avi_filter}, {wszVideoMpeg, video_mpeg_filter}, + {wszAppPostscript, application_postscript_filter}, {wszAppPdf, application_pdf_filter}, {wszAppXZip, application_xzip_filter}, {wszAppXGzip, application_xgzip_filter}, @@ -676,6 +704,21 @@ HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer, return E_FAIL; } +/*********************************************************************** + * GetClassFileOrMime (URLMON.@) + * + * Determines the class ID from the bind context, file name or MIME type. + */ +HRESULT WINAPI GetClassFileOrMime(LPBC pBC, LPCWSTR pszFilename, + LPVOID pBuffer, DWORD cbBuffer, LPCWSTR pszMimeType, DWORD dwReserved, + CLSID *pclsid) +{ + FIXME("(%p, %s, %p, %d, %p, 0x%08x, %p): stub\n", pBC, + debugstr_w(pszFilename), pBuffer, cbBuffer, debugstr_w(pszMimeType), + dwReserved, pclsid); + return E_NOTIMPL; +} + /*********************************************************************** * Extract (URLMON.@) */ diff --git a/reactos/dll/win32/urlmon/urlmon_main.h b/reactos/dll/win32/urlmon/urlmon_main.h index 743ab48a1a4..aeb0eb22ca2 100644 --- a/reactos/dll/win32/urlmon/urlmon_main.h +++ b/reactos/dll/win32/urlmon/urlmon_main.h @@ -29,6 +29,7 @@ extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT FileProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); +extern HRESULT HttpSProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); @@ -43,7 +44,7 @@ static inline void URLMON_UnlockModule(void) { InterlockedDecrement( &URLMON_ref #define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ## Vtbl))) typedef struct -{ +{ const IStreamVtbl *lpVtbl; LONG ref; HANDLE handle; @@ -62,4 +63,24 @@ HRESULT start_binding(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv); HRESULT create_binding_protocol(LPCWSTR url, IInternetProtocol **protocol); +static inline void *urlmon_alloc(size_t len) +{ + return HeapAlloc(GetProcessHeap(), 0, len); +} + +static inline void *urlmon_alloc_zero(size_t len) +{ + return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); +} + +static inline void *urlmon_realloc(void *mem, size_t len) +{ + return HeapReAlloc(GetProcessHeap(), 0, mem, len); +} + +static inline BOOL urlmon_free(void *mem) +{ + return HeapFree(GetProcessHeap(), 0, mem); +} + #endif /* __WINE_URLMON_MAIN_H */