2 * Based on ../shell32/memorystream.c
4 * Copyright 1999 Juergen Schmied
5 * Copyright 2003 Mike McCormack for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "urlmon_main.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
33 typedef struct ProxyBindStatusCallback
35 IBindStatusCallback IBindStatusCallback_iface;
37 IBindStatusCallback *pBSC;
38 } ProxyBindStatusCallback;
40 static inline ProxyBindStatusCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
42 return CONTAINING_RECORD(iface, ProxyBindStatusCallback, IBindStatusCallback_iface);
45 static HRESULT WINAPI ProxyBindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
47 if (IsEqualGUID(&IID_IBindStatusCallback, riid) ||
48 IsEqualGUID(&IID_IUnknown, riid))
51 IUnknown_AddRef(iface);
59 static ULONG WINAPI ProxyBindStatusCallback_AddRef(IBindStatusCallback *iface)
64 static ULONG WINAPI ProxyBindStatusCallback_Release(IBindStatusCallback *iface)
69 static HRESULT WINAPI ProxyBindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
72 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
75 return IBindStatusCallback_OnStartBinding(This->pBSC, dwReserved, pib);
80 static HRESULT WINAPI ProxyBindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
82 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
85 return IBindStatusCallback_GetPriority(This->pBSC, pnPriority);
90 static HRESULT WINAPI ProxyBindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
92 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
95 return IBindStatusCallback_OnLowResource(This->pBSC, reserved);
100 static HRESULT WINAPI ProxyBindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
101 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
103 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
106 return IBindStatusCallback_OnProgress(This->pBSC, ulProgress,
107 ulProgressMax, ulStatusCode,
113 static HRESULT WINAPI ProxyBindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
115 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
118 return IBindStatusCallback_OnStopBinding(This->pBSC, hresult, szError);
123 static HRESULT WINAPI ProxyBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
125 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
128 return IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo);
133 static HRESULT WINAPI ProxyBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
134 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
136 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
139 return IBindStatusCallback_OnDataAvailable(This->pBSC, grfBSCF, dwSize,
140 pformatetc, pstgmed);
145 static HRESULT WINAPI ProxyBindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
147 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
150 return IBindStatusCallback_OnObjectAvailable(This->pBSC, riid, punk);
155 static HRESULT WINAPI BlockingBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
156 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
161 static const IBindStatusCallbackVtbl BlockingBindStatusCallbackVtbl =
163 ProxyBindStatusCallback_QueryInterface,
164 ProxyBindStatusCallback_AddRef,
165 ProxyBindStatusCallback_Release,
166 ProxyBindStatusCallback_OnStartBinding,
167 ProxyBindStatusCallback_GetPriority,
168 ProxyBindStatusCallback_OnLowResource,
169 ProxyBindStatusCallback_OnProgress,
170 ProxyBindStatusCallback_OnStopBinding,
171 ProxyBindStatusCallback_GetBindInfo,
172 BlockingBindStatusCallback_OnDataAvailable,
173 ProxyBindStatusCallback_OnObjectAvailable
176 static HRESULT WINAPI AsyncBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
178 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
179 HRESULT hr = IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo);
180 *grfBINDF |= BINDF_PULLDATA | BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE;
184 static const IBindStatusCallbackVtbl AsyncBindStatusCallbackVtbl =
186 ProxyBindStatusCallback_QueryInterface,
187 ProxyBindStatusCallback_AddRef,
188 ProxyBindStatusCallback_Release,
189 ProxyBindStatusCallback_OnStartBinding,
190 ProxyBindStatusCallback_GetPriority,
191 ProxyBindStatusCallback_OnLowResource,
192 ProxyBindStatusCallback_OnProgress,
193 ProxyBindStatusCallback_OnStopBinding,
194 AsyncBindStatusCallback_GetBindInfo,
195 ProxyBindStatusCallback_OnDataAvailable,
196 ProxyBindStatusCallback_OnObjectAvailable
199 static HRESULT URLStartDownload(LPCWSTR szURL, LPSTREAM *ppStream, IBindStatusCallback *pBSC)
207 hr = CreateURLMoniker(NULL, szURL, &pMoniker);
211 hr = CreateBindCtx(0, &pbc);
214 IMoniker_Release(pMoniker);
218 hr = RegisterBindStatusCallback(pbc, pBSC, NULL, 0);
221 IBindCtx_Release(pbc);
222 IMoniker_Release(pMoniker);
226 hr = IMoniker_BindToStorage(pMoniker, pbc, NULL, &IID_IStream, (void **)ppStream);
228 /* BindToStorage returning E_PENDING because it's asynchronous is not an error */
229 if (hr == E_PENDING) hr = S_OK;
231 IBindCtx_Release(pbc);
232 IMoniker_Release(pMoniker);
237 /***********************************************************************
238 * URLOpenBlockingStreamA (URLMON.@)
240 HRESULT WINAPI URLOpenBlockingStreamA(LPUNKNOWN pCaller, LPCSTR szURL,
241 LPSTREAM *ppStream, DWORD dwReserved,
242 LPBINDSTATUSCALLBACK lpfnCB)
248 TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, szURL, ppStream, dwReserved, lpfnCB);
250 if (!szURL || !ppStream)
253 len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
254 szURLW = heap_alloc(len * sizeof(WCHAR));
258 return E_OUTOFMEMORY;
260 MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len);
262 hr = URLOpenBlockingStreamW(pCaller, szURLW, ppStream, dwReserved, lpfnCB);
269 /***********************************************************************
270 * URLOpenBlockingStreamW (URLMON.@)
272 HRESULT WINAPI URLOpenBlockingStreamW(LPUNKNOWN pCaller, LPCWSTR szURL,
273 LPSTREAM *ppStream, DWORD dwReserved,
274 LPBINDSTATUSCALLBACK lpfnCB)
276 ProxyBindStatusCallback blocking_bsc;
278 TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, debugstr_w(szURL), ppStream,
281 if (!szURL || !ppStream)
284 blocking_bsc.IBindStatusCallback_iface.lpVtbl = &BlockingBindStatusCallbackVtbl;
285 blocking_bsc.pBSC = lpfnCB;
287 return URLStartDownload(szURL, ppStream, &blocking_bsc.IBindStatusCallback_iface);
290 /***********************************************************************
291 * URLOpenStreamA (URLMON.@)
293 HRESULT WINAPI URLOpenStreamA(LPUNKNOWN pCaller, LPCSTR szURL, DWORD dwReserved,
294 LPBINDSTATUSCALLBACK lpfnCB)
300 TRACE("(%p, %s, 0x%x, %p)\n", pCaller, szURL, dwReserved, lpfnCB);
305 len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
306 szURLW = heap_alloc(len * sizeof(WCHAR));
308 return E_OUTOFMEMORY;
309 MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len);
311 hr = URLOpenStreamW(pCaller, szURLW, dwReserved, lpfnCB);
318 /***********************************************************************
319 * URLOpenStreamW (URLMON.@)
321 HRESULT WINAPI URLOpenStreamW(LPUNKNOWN pCaller, LPCWSTR szURL, DWORD dwReserved,
322 LPBINDSTATUSCALLBACK lpfnCB)
325 ProxyBindStatusCallback async_bsc;
328 TRACE("(%p, %s, 0x%x, %p)\n", pCaller, debugstr_w(szURL), dwReserved,
334 async_bsc.IBindStatusCallback_iface.lpVtbl = &AsyncBindStatusCallbackVtbl;
335 async_bsc.pBSC = lpfnCB;
337 hr = URLStartDownload(szURL, &pStream, &async_bsc.IBindStatusCallback_iface);
338 if (SUCCEEDED(hr) && pStream)
339 IStream_Release(pStream);