xref: /reactos/dll/win32/urlmon/umstream.c (revision 143d4fdb)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Based on ../shell32/memorystream.c
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 1999 Juergen Schmied
5c2c66affSColin Finck  * Copyright 2003 Mike McCormack for CodeWeavers
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck  */
21c2c66affSColin Finck 
22c2c66affSColin Finck #include "urlmon_main.h"
23c2c66affSColin Finck 
24*143d4fdbSAmine Khaldi #include "winreg.h"
25*143d4fdbSAmine Khaldi #include "wine/winternl.h"
26*143d4fdbSAmine Khaldi #include "wininet.h"
27*143d4fdbSAmine Khaldi #include "shlwapi.h"
28*143d4fdbSAmine Khaldi 
29*143d4fdbSAmine Khaldi #include "wine/debug.h"
30*143d4fdbSAmine Khaldi 
31*143d4fdbSAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
32*143d4fdbSAmine Khaldi 
33c2c66affSColin Finck typedef struct ProxyBindStatusCallback
34c2c66affSColin Finck {
35c2c66affSColin Finck     IBindStatusCallback IBindStatusCallback_iface;
36c2c66affSColin Finck 
37c2c66affSColin Finck     IBindStatusCallback *pBSC;
38c2c66affSColin Finck } ProxyBindStatusCallback;
39c2c66affSColin Finck 
impl_from_IBindStatusCallback(IBindStatusCallback * iface)40c2c66affSColin Finck static inline ProxyBindStatusCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
41c2c66affSColin Finck {
42c2c66affSColin Finck     return CONTAINING_RECORD(iface, ProxyBindStatusCallback, IBindStatusCallback_iface);
43c2c66affSColin Finck }
44c2c66affSColin Finck 
ProxyBindStatusCallback_QueryInterface(IBindStatusCallback * iface,REFIID riid,void ** ppv)45c2c66affSColin Finck static HRESULT WINAPI ProxyBindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
46c2c66affSColin Finck {
47c2c66affSColin Finck     if (IsEqualGUID(&IID_IBindStatusCallback, riid) ||
48c2c66affSColin Finck         IsEqualGUID(&IID_IUnknown, riid))
49c2c66affSColin Finck     {
50c2c66affSColin Finck         *ppv = iface;
51c2c66affSColin Finck         IBindStatusCallback_AddRef(iface);
52c2c66affSColin Finck         return S_OK;
53c2c66affSColin Finck     }
54c2c66affSColin Finck 
55c2c66affSColin Finck     *ppv = NULL;
56c2c66affSColin Finck     return E_NOINTERFACE;
57c2c66affSColin Finck }
58c2c66affSColin Finck 
ProxyBindStatusCallback_AddRef(IBindStatusCallback * iface)59c2c66affSColin Finck static ULONG WINAPI ProxyBindStatusCallback_AddRef(IBindStatusCallback *iface)
60c2c66affSColin Finck {
61c2c66affSColin Finck     return 2;
62c2c66affSColin Finck }
63c2c66affSColin Finck 
ProxyBindStatusCallback_Release(IBindStatusCallback * iface)64c2c66affSColin Finck static ULONG WINAPI ProxyBindStatusCallback_Release(IBindStatusCallback *iface)
65c2c66affSColin Finck {
66c2c66affSColin Finck     return 1;
67c2c66affSColin Finck }
68c2c66affSColin Finck 
ProxyBindStatusCallback_OnStartBinding(IBindStatusCallback * iface,DWORD dwReserved,IBinding * pib)69c2c66affSColin Finck static HRESULT WINAPI ProxyBindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
70c2c66affSColin Finck                                                IBinding *pib)
71c2c66affSColin Finck {
72c2c66affSColin Finck     ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
73c2c66affSColin Finck 
74c2c66affSColin Finck     if(This->pBSC)
75c2c66affSColin Finck         return IBindStatusCallback_OnStartBinding(This->pBSC, dwReserved, pib);
76c2c66affSColin Finck 
77c2c66affSColin Finck     return S_OK;
78c2c66affSColin Finck }
79c2c66affSColin Finck 
ProxyBindStatusCallback_GetPriority(IBindStatusCallback * iface,LONG * pnPriority)80c2c66affSColin Finck static HRESULT WINAPI ProxyBindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
81c2c66affSColin Finck {
82c2c66affSColin Finck     ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
83c2c66affSColin Finck 
84c2c66affSColin Finck     if(This->pBSC)
85c2c66affSColin Finck         return IBindStatusCallback_GetPriority(This->pBSC, pnPriority);
86c2c66affSColin Finck 
87c2c66affSColin Finck     return S_OK;
88c2c66affSColin Finck }
89c2c66affSColin Finck 
ProxyBindStatusCallback_OnLowResource(IBindStatusCallback * iface,DWORD reserved)90c2c66affSColin Finck static HRESULT WINAPI ProxyBindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
91c2c66affSColin Finck {
92c2c66affSColin Finck     ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
93c2c66affSColin Finck 
94c2c66affSColin Finck     if(This->pBSC)
95c2c66affSColin Finck         return IBindStatusCallback_OnLowResource(This->pBSC, reserved);
96c2c66affSColin Finck 
97c2c66affSColin Finck     return S_OK;
98c2c66affSColin Finck }
99c2c66affSColin Finck 
ProxyBindStatusCallback_OnProgress(IBindStatusCallback * iface,ULONG ulProgress,ULONG ulProgressMax,ULONG ulStatusCode,LPCWSTR szStatusText)100c2c66affSColin Finck static HRESULT WINAPI ProxyBindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
101c2c66affSColin Finck                                            ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
102c2c66affSColin Finck {
103c2c66affSColin Finck     ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
104c2c66affSColin Finck 
105c2c66affSColin Finck     if(This->pBSC)
106c2c66affSColin Finck         return IBindStatusCallback_OnProgress(This->pBSC, ulProgress,
107c2c66affSColin Finck                                           ulProgressMax, ulStatusCode,
108c2c66affSColin Finck                                           szStatusText);
109c2c66affSColin Finck 
110c2c66affSColin Finck     return S_OK;
111c2c66affSColin Finck }
112c2c66affSColin Finck 
ProxyBindStatusCallback_OnStopBinding(IBindStatusCallback * iface,HRESULT hresult,LPCWSTR szError)113c2c66affSColin Finck static HRESULT WINAPI ProxyBindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
114c2c66affSColin Finck {
115c2c66affSColin Finck     ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
116c2c66affSColin Finck 
117c2c66affSColin Finck     if(This->pBSC)
118c2c66affSColin Finck         return IBindStatusCallback_OnStopBinding(This->pBSC, hresult, szError);
119c2c66affSColin Finck 
120c2c66affSColin Finck     return S_OK;
121c2c66affSColin Finck }
122c2c66affSColin Finck 
ProxyBindStatusCallback_GetBindInfo(IBindStatusCallback * iface,DWORD * grfBINDF,BINDINFO * pbindinfo)123c2c66affSColin Finck static HRESULT WINAPI ProxyBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
124c2c66affSColin Finck {
125c2c66affSColin Finck     DWORD size = pbindinfo->cbSize;
126c2c66affSColin Finck     ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
127c2c66affSColin Finck 
128c2c66affSColin Finck     if(This->pBSC)
129c2c66affSColin Finck         return IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo);
130c2c66affSColin Finck 
131c2c66affSColin Finck     memset(pbindinfo, 0, size);
132c2c66affSColin Finck     pbindinfo->cbSize = size;
133c2c66affSColin Finck 
134c2c66affSColin Finck     *grfBINDF = 0;
135c2c66affSColin Finck 
136c2c66affSColin Finck     return S_OK;
137c2c66affSColin Finck }
138c2c66affSColin Finck 
ProxyBindStatusCallback_OnDataAvailable(IBindStatusCallback * iface,DWORD grfBSCF,DWORD dwSize,FORMATETC * pformatetc,STGMEDIUM * pstgmed)139c2c66affSColin Finck static HRESULT WINAPI ProxyBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
140c2c66affSColin Finck                                                               DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
141c2c66affSColin Finck {
142c2c66affSColin Finck     ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
143c2c66affSColin Finck 
144c2c66affSColin Finck     if(This->pBSC)
145c2c66affSColin Finck         return IBindStatusCallback_OnDataAvailable(This->pBSC, grfBSCF, dwSize,
146c2c66affSColin Finck                                                pformatetc, pstgmed);
147c2c66affSColin Finck 
148c2c66affSColin Finck     return S_OK;
149c2c66affSColin Finck }
150c2c66affSColin Finck 
ProxyBindStatusCallback_OnObjectAvailable(IBindStatusCallback * iface,REFIID riid,IUnknown * punk)151c2c66affSColin Finck static HRESULT WINAPI ProxyBindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
152c2c66affSColin Finck {
153c2c66affSColin Finck     ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
154c2c66affSColin Finck 
155c2c66affSColin Finck     if(This->pBSC)
156c2c66affSColin Finck         return IBindStatusCallback_OnObjectAvailable(This->pBSC, riid, punk);
157c2c66affSColin Finck 
158c2c66affSColin Finck     return S_OK;
159c2c66affSColin Finck }
160c2c66affSColin Finck 
BlockingBindStatusCallback_OnDataAvailable(IBindStatusCallback * iface,DWORD grfBSCF,DWORD dwSize,FORMATETC * pformatetc,STGMEDIUM * pstgmed)161c2c66affSColin Finck static HRESULT WINAPI BlockingBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
162c2c66affSColin Finck                                                                  DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
163c2c66affSColin Finck {
164c2c66affSColin Finck     return S_OK;
165c2c66affSColin Finck }
166c2c66affSColin Finck 
167c2c66affSColin Finck static const IBindStatusCallbackVtbl BlockingBindStatusCallbackVtbl =
168c2c66affSColin Finck {
169c2c66affSColin Finck     ProxyBindStatusCallback_QueryInterface,
170c2c66affSColin Finck     ProxyBindStatusCallback_AddRef,
171c2c66affSColin Finck     ProxyBindStatusCallback_Release,
172c2c66affSColin Finck     ProxyBindStatusCallback_OnStartBinding,
173c2c66affSColin Finck     ProxyBindStatusCallback_GetPriority,
174c2c66affSColin Finck     ProxyBindStatusCallback_OnLowResource,
175c2c66affSColin Finck     ProxyBindStatusCallback_OnProgress,
176c2c66affSColin Finck     ProxyBindStatusCallback_OnStopBinding,
177c2c66affSColin Finck     ProxyBindStatusCallback_GetBindInfo,
178c2c66affSColin Finck     BlockingBindStatusCallback_OnDataAvailable,
179c2c66affSColin Finck     ProxyBindStatusCallback_OnObjectAvailable
180c2c66affSColin Finck };
181c2c66affSColin Finck 
AsyncBindStatusCallback_GetBindInfo(IBindStatusCallback * iface,DWORD * grfBINDF,BINDINFO * pbindinfo)182c2c66affSColin Finck static HRESULT WINAPI AsyncBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
183c2c66affSColin Finck {
184c2c66affSColin Finck     ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
185c2c66affSColin Finck     HRESULT hr = S_OK;
186c2c66affSColin Finck 
187c2c66affSColin Finck     if(This->pBSC)
188c2c66affSColin Finck         hr = IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo);
189c2c66affSColin Finck     else{
190c2c66affSColin Finck         DWORD size = pbindinfo->cbSize;
191c2c66affSColin Finck         memset(pbindinfo, 0, size);
192c2c66affSColin Finck         pbindinfo->cbSize = size;
193c2c66affSColin Finck 
194c2c66affSColin Finck         *grfBINDF = 0;
195c2c66affSColin Finck     }
196c2c66affSColin Finck 
197c2c66affSColin Finck     *grfBINDF |= BINDF_PULLDATA | BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE;
198c2c66affSColin Finck 
199c2c66affSColin Finck     return hr;
200c2c66affSColin Finck }
201c2c66affSColin Finck 
202c2c66affSColin Finck static const IBindStatusCallbackVtbl AsyncBindStatusCallbackVtbl =
203c2c66affSColin Finck {
204c2c66affSColin Finck     ProxyBindStatusCallback_QueryInterface,
205c2c66affSColin Finck     ProxyBindStatusCallback_AddRef,
206c2c66affSColin Finck     ProxyBindStatusCallback_Release,
207c2c66affSColin Finck     ProxyBindStatusCallback_OnStartBinding,
208c2c66affSColin Finck     ProxyBindStatusCallback_GetPriority,
209c2c66affSColin Finck     ProxyBindStatusCallback_OnLowResource,
210c2c66affSColin Finck     ProxyBindStatusCallback_OnProgress,
211c2c66affSColin Finck     ProxyBindStatusCallback_OnStopBinding,
212c2c66affSColin Finck     AsyncBindStatusCallback_GetBindInfo,
213c2c66affSColin Finck     ProxyBindStatusCallback_OnDataAvailable,
214c2c66affSColin Finck     ProxyBindStatusCallback_OnObjectAvailable
215c2c66affSColin Finck };
216c2c66affSColin Finck 
URLStartDownload(LPCWSTR szURL,LPSTREAM * ppStream,IBindStatusCallback * pBSC)217c2c66affSColin Finck static HRESULT URLStartDownload(LPCWSTR szURL, LPSTREAM *ppStream, IBindStatusCallback *pBSC)
218c2c66affSColin Finck {
219c2c66affSColin Finck     HRESULT hr;
220c2c66affSColin Finck     IMoniker *pMoniker;
221c2c66affSColin Finck     IBindCtx *pbc;
222c2c66affSColin Finck 
223c2c66affSColin Finck     *ppStream = NULL;
224c2c66affSColin Finck 
225c2c66affSColin Finck     hr = CreateURLMoniker(NULL, szURL, &pMoniker);
226c2c66affSColin Finck     if (FAILED(hr))
227c2c66affSColin Finck         return hr;
228c2c66affSColin Finck 
229c2c66affSColin Finck     hr = CreateBindCtx(0, &pbc);
230c2c66affSColin Finck     if (FAILED(hr))
231c2c66affSColin Finck     {
232c2c66affSColin Finck         IMoniker_Release(pMoniker);
233c2c66affSColin Finck         return hr;
234c2c66affSColin Finck     }
235c2c66affSColin Finck 
236c2c66affSColin Finck     hr = RegisterBindStatusCallback(pbc, pBSC, NULL, 0);
237c2c66affSColin Finck     if (FAILED(hr))
238c2c66affSColin Finck     {
239c2c66affSColin Finck         IBindCtx_Release(pbc);
240c2c66affSColin Finck         IMoniker_Release(pMoniker);
241c2c66affSColin Finck         return hr;
242c2c66affSColin Finck     }
243c2c66affSColin Finck 
244c2c66affSColin Finck     hr = IMoniker_BindToStorage(pMoniker, pbc, NULL, &IID_IStream, (void **)ppStream);
245c2c66affSColin Finck 
246c2c66affSColin Finck     /* BindToStorage returning E_PENDING because it's asynchronous is not an error */
247c2c66affSColin Finck     if (hr == E_PENDING) hr = S_OK;
248c2c66affSColin Finck 
249c2c66affSColin Finck     IBindCtx_Release(pbc);
250c2c66affSColin Finck     IMoniker_Release(pMoniker);
251c2c66affSColin Finck 
252c2c66affSColin Finck     return hr;
253c2c66affSColin Finck }
254c2c66affSColin Finck 
255c2c66affSColin Finck /***********************************************************************
256c2c66affSColin Finck  *		URLOpenBlockingStreamA (URLMON.@)
257c2c66affSColin Finck  */
URLOpenBlockingStreamA(LPUNKNOWN pCaller,LPCSTR szURL,LPSTREAM * ppStream,DWORD dwReserved,LPBINDSTATUSCALLBACK lpfnCB)258c2c66affSColin Finck HRESULT WINAPI URLOpenBlockingStreamA(LPUNKNOWN pCaller, LPCSTR szURL,
259c2c66affSColin Finck                                       LPSTREAM *ppStream, DWORD dwReserved,
260c2c66affSColin Finck                                       LPBINDSTATUSCALLBACK lpfnCB)
261c2c66affSColin Finck {
262c2c66affSColin Finck     LPWSTR szURLW;
263c2c66affSColin Finck     int len;
264c2c66affSColin Finck     HRESULT hr;
265c2c66affSColin Finck 
266c2c66affSColin Finck     TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, szURL, ppStream, dwReserved, lpfnCB);
267c2c66affSColin Finck 
268c2c66affSColin Finck     if (!szURL || !ppStream)
269c2c66affSColin Finck         return E_INVALIDARG;
270c2c66affSColin Finck 
271c2c66affSColin Finck     len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
272c2c66affSColin Finck     szURLW = heap_alloc(len * sizeof(WCHAR));
273c2c66affSColin Finck     if (!szURLW)
274c2c66affSColin Finck     {
275c2c66affSColin Finck         *ppStream = NULL;
276c2c66affSColin Finck         return E_OUTOFMEMORY;
277c2c66affSColin Finck     }
278c2c66affSColin Finck     MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len);
279c2c66affSColin Finck 
280c2c66affSColin Finck     hr = URLOpenBlockingStreamW(pCaller, szURLW, ppStream, dwReserved, lpfnCB);
281c2c66affSColin Finck 
282c2c66affSColin Finck     heap_free(szURLW);
283c2c66affSColin Finck 
284c2c66affSColin Finck     return hr;
285c2c66affSColin Finck }
286c2c66affSColin Finck 
287c2c66affSColin Finck /***********************************************************************
288c2c66affSColin Finck  *		URLOpenBlockingStreamW (URLMON.@)
289c2c66affSColin Finck  */
URLOpenBlockingStreamW(LPUNKNOWN pCaller,LPCWSTR szURL,LPSTREAM * ppStream,DWORD dwReserved,LPBINDSTATUSCALLBACK lpfnCB)290c2c66affSColin Finck HRESULT WINAPI URLOpenBlockingStreamW(LPUNKNOWN pCaller, LPCWSTR szURL,
291c2c66affSColin Finck                                       LPSTREAM *ppStream, DWORD dwReserved,
292c2c66affSColin Finck                                       LPBINDSTATUSCALLBACK lpfnCB)
293c2c66affSColin Finck {
294c2c66affSColin Finck     ProxyBindStatusCallback blocking_bsc;
295c2c66affSColin Finck 
296c2c66affSColin Finck     TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, debugstr_w(szURL), ppStream,
297c2c66affSColin Finck           dwReserved, lpfnCB);
298c2c66affSColin Finck 
299c2c66affSColin Finck     if (!szURL || !ppStream)
300c2c66affSColin Finck         return E_INVALIDARG;
301c2c66affSColin Finck 
302c2c66affSColin Finck     blocking_bsc.IBindStatusCallback_iface.lpVtbl = &BlockingBindStatusCallbackVtbl;
303c2c66affSColin Finck     blocking_bsc.pBSC = lpfnCB;
304c2c66affSColin Finck 
305c2c66affSColin Finck     return URLStartDownload(szURL, ppStream, &blocking_bsc.IBindStatusCallback_iface);
306c2c66affSColin Finck }
307c2c66affSColin Finck 
308c2c66affSColin Finck /***********************************************************************
309c2c66affSColin Finck  *		URLOpenStreamA (URLMON.@)
310c2c66affSColin Finck  */
URLOpenStreamA(LPUNKNOWN pCaller,LPCSTR szURL,DWORD dwReserved,LPBINDSTATUSCALLBACK lpfnCB)311c2c66affSColin Finck HRESULT WINAPI URLOpenStreamA(LPUNKNOWN pCaller, LPCSTR szURL, DWORD dwReserved,
312c2c66affSColin Finck                               LPBINDSTATUSCALLBACK lpfnCB)
313c2c66affSColin Finck {
314c2c66affSColin Finck     LPWSTR szURLW;
315c2c66affSColin Finck     int len;
316c2c66affSColin Finck     HRESULT hr;
317c2c66affSColin Finck 
318c2c66affSColin Finck     TRACE("(%p, %s, 0x%x, %p)\n", pCaller, szURL, dwReserved, lpfnCB);
319c2c66affSColin Finck 
320c2c66affSColin Finck     if (!szURL)
321c2c66affSColin Finck         return E_INVALIDARG;
322c2c66affSColin Finck 
323c2c66affSColin Finck     len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
324c2c66affSColin Finck     szURLW = heap_alloc(len * sizeof(WCHAR));
325c2c66affSColin Finck     if (!szURLW)
326c2c66affSColin Finck         return E_OUTOFMEMORY;
327c2c66affSColin Finck     MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len);
328c2c66affSColin Finck 
329c2c66affSColin Finck     hr = URLOpenStreamW(pCaller, szURLW, dwReserved, lpfnCB);
330c2c66affSColin Finck 
331c2c66affSColin Finck     heap_free(szURLW);
332c2c66affSColin Finck 
333c2c66affSColin Finck     return hr;
334c2c66affSColin Finck }
335c2c66affSColin Finck 
336c2c66affSColin Finck /***********************************************************************
337c2c66affSColin Finck  *		URLOpenStreamW (URLMON.@)
338c2c66affSColin Finck  */
URLOpenStreamW(LPUNKNOWN pCaller,LPCWSTR szURL,DWORD dwReserved,LPBINDSTATUSCALLBACK lpfnCB)339c2c66affSColin Finck HRESULT WINAPI URLOpenStreamW(LPUNKNOWN pCaller, LPCWSTR szURL, DWORD dwReserved,
340c2c66affSColin Finck                               LPBINDSTATUSCALLBACK lpfnCB)
341c2c66affSColin Finck {
342c2c66affSColin Finck     HRESULT hr;
343c2c66affSColin Finck     ProxyBindStatusCallback async_bsc;
344c2c66affSColin Finck     IStream *pStream;
345c2c66affSColin Finck 
346c2c66affSColin Finck     TRACE("(%p, %s, 0x%x, %p)\n", pCaller, debugstr_w(szURL), dwReserved,
347c2c66affSColin Finck           lpfnCB);
348c2c66affSColin Finck 
349c2c66affSColin Finck     if (!szURL)
350c2c66affSColin Finck         return E_INVALIDARG;
351c2c66affSColin Finck 
352c2c66affSColin Finck     async_bsc.IBindStatusCallback_iface.lpVtbl = &AsyncBindStatusCallbackVtbl;
353c2c66affSColin Finck     async_bsc.pBSC = lpfnCB;
354c2c66affSColin Finck 
355c2c66affSColin Finck     hr = URLStartDownload(szURL, &pStream, &async_bsc.IBindStatusCallback_iface);
356c2c66affSColin Finck     if (SUCCEEDED(hr) && pStream)
357c2c66affSColin Finck         IStream_Release(pStream);
358c2c66affSColin Finck 
359c2c66affSColin Finck     return hr;
360c2c66affSColin Finck }
361