Rob Shearman : urlmon: Implement URLOpenBlockingStreamA/
W and URLOpenStreamA/W.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Aug 8 08:59:54 CDT 2007
Module: wine
Branch: master
Commit: 9debcb8f49a97d5db3a4d24e5f3eb13c367590d6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9debcb8f49a97d5db3a4d24e5f3eb13c367590d6
Author: Rob Shearman <rob at codeweavers.com>
Date: Fri Aug 3 22:11:31 2007 +0100
urlmon: Implement URLOpenBlockingStreamA/W and URLOpenStreamA/W.
---
dlls/urlmon/umstream.c | 241 +++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 227 insertions(+), 14 deletions(-)
diff --git a/dlls/urlmon/umstream.c b/dlls/urlmon/umstream.c
index ec2b306..9ebf232 100644
--- a/dlls/urlmon/umstream.c
+++ b/dlls/urlmon/umstream.c
@@ -379,6 +379,173 @@ static const IStreamVtbl stvt =
};
+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;
+ return IBindStatusCallback_OnStartBinding(This->pBSC, dwReserved, pib);
+}
+
+static HRESULT WINAPI ProxyBindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
+{
+ ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ return IBindStatusCallback_GetPriority(This->pBSC, pnPriority);
+}
+
+static HRESULT WINAPI ProxyBindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
+{
+ ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ return IBindStatusCallback_OnLowResource(This->pBSC, reserved);
+}
+
+static HRESULT WINAPI ProxyBindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
+ ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
+{
+ ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ return IBindStatusCallback_OnProgress(This->pBSC, ulProgress,
+ ulProgressMax, ulStatusCode,
+ szStatusText);
+}
+
+static HRESULT WINAPI ProxyBindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
+{
+ ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ return IBindStatusCallback_OnStopBinding(This->pBSC, hresult, szError);
+}
+
+static HRESULT WINAPI ProxyBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
+{
+ ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ return IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo);
+}
+
+static HRESULT WINAPI ProxyBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
+ DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
+{
+ ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ return IBindStatusCallback_OnDataAvailable(This->pBSC, grfBSCF, dwSize,
+ pformatetc, pstgmed);
+}
+
+static HRESULT WINAPI ProxyBindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
+{
+ ProxyBindStatusCallback *This = (ProxyBindStatusCallback *)iface;
+ return IBindStatusCallback_OnObjectAvailable(This->pBSC, riid, punk);
+}
+
+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.@)
*/
@@ -386,9 +553,23 @@ HRESULT WINAPI URLOpenBlockingStreamA(LPUNKNOWN pCaller, LPCSTR szURL,
LPSTREAM *ppStream, DWORD dwReserved,
LPBINDSTATUSCALLBACK lpfnCB)
{
- FIXME("(%p, %s, %p, 0x%x, %p): stub\n", pCaller, szURL, ppStream, dwReserved, lpfnCB);
- *ppStream = NULL;
- return E_NOTIMPL;
+ LPWSTR szURLW;
+ int len;
+ HRESULT hr;
+
+ TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, szURL, ppStream, dwReserved, lpfnCB);
+
+ len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
+ szURLW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!szURLW)
+ return E_OUTOFMEMORY;
+ MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len);
+
+ hr = URLOpenBlockingStreamW(pCaller, szURLW, ppStream, dwReserved, lpfnCB);
+
+ HeapFree(GetProcessHeap(), 0, szURLW);
+
+ return hr;
}
/***********************************************************************
@@ -398,29 +579,61 @@ HRESULT WINAPI URLOpenBlockingStreamW(LPUNKNOWN pCaller, LPCWSTR szURL,
LPSTREAM *ppStream, DWORD dwReserved,
LPBINDSTATUSCALLBACK lpfnCB)
{
- FIXME("(%p, %s, %p, 0x%x, %p): stub\n", pCaller, debugstr_w(szURL), ppStream,
+ ProxyBindStatusCallback blocking_bsc;
+
+ TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, debugstr_w(szURL), ppStream,
dwReserved, lpfnCB);
- *ppStream = NULL;
- return E_NOTIMPL;
+
+ blocking_bsc.lpVtbl = &BlockingBindStatusCallbackVtbl;
+ blocking_bsc.pBSC = lpfnCB;
+
+ return URLStartDownload(szURL, ppStream, (IBindStatusCallback *)&blocking_bsc);
}
/***********************************************************************
-* URLOpenStreamA (URLMON.@)
-*/
+ * URLOpenStreamA (URLMON.@)
+ */
HRESULT WINAPI URLOpenStreamA(LPUNKNOWN pCaller, LPCSTR szURL, DWORD dwReserved,
LPBINDSTATUSCALLBACK lpfnCB)
{
- FIXME("(%p, %s, 0x%x, %p): stub\n", pCaller, szURL, dwReserved, lpfnCB);
- return E_NOTIMPL;
+ LPWSTR szURLW;
+ int len;
+ HRESULT hr;
+
+ TRACE("(%p, %s, 0x%x, %p)\n", pCaller, szURL, dwReserved, lpfnCB);
+
+ len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
+ szURLW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!szURLW)
+ return E_OUTOFMEMORY;
+ MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len);
+
+ hr = URLOpenStreamW(pCaller, szURLW, dwReserved, lpfnCB);
+
+ HeapFree(GetProcessHeap(), 0, szURLW);
+
+ return hr;
}
/***********************************************************************
-* URLOpenStreamW (URLMON.@)
-*/
+ * URLOpenStreamW (URLMON.@)
+ */
HRESULT WINAPI URLOpenStreamW(LPUNKNOWN pCaller, LPCWSTR szURL, DWORD dwReserved,
LPBINDSTATUSCALLBACK lpfnCB)
{
- FIXME("(%p, %s, 0x%x, %p): stub\n", pCaller, debugstr_w(szURL), dwReserved,
+ HRESULT hr;
+ ProxyBindStatusCallback async_bsc;
+ IStream *pStream;
+
+ TRACE("(%p, %s, 0x%x, %p)\n", pCaller, debugstr_w(szURL), dwReserved,
lpfnCB);
- return E_NOTIMPL;
+
+ async_bsc.lpVtbl = &AsyncBindStatusCallbackVtbl;
+ async_bsc.pBSC = lpfnCB;
+
+ hr = URLStartDownload(szURL, &pStream, (IBindStatusCallback *)&async_bsc);
+ if (SUCCEEDED(hr) && pStream)
+ IStream_Release(pStream);
+
+ return hr;
}
More information about the wine-cvs
mailing list