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