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 IBindStatusCallback_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 DWORD size
= pbindinfo
->cbSize
;
126 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
129 return IBindStatusCallback_GetBindInfo(This
->pBSC
, grfBINDF
, pbindinfo
);
131 memset(pbindinfo
, 0, size
);
132 pbindinfo
->cbSize
= size
;
139 static HRESULT WINAPI
ProxyBindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
, DWORD grfBSCF
,
140 DWORD dwSize
, FORMATETC
* pformatetc
, STGMEDIUM
* pstgmed
)
142 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
145 return IBindStatusCallback_OnDataAvailable(This
->pBSC
, grfBSCF
, dwSize
,
146 pformatetc
, pstgmed
);
151 static HRESULT WINAPI
ProxyBindStatusCallback_OnObjectAvailable(IBindStatusCallback
*iface
, REFIID riid
, IUnknown
*punk
)
153 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
156 return IBindStatusCallback_OnObjectAvailable(This
->pBSC
, riid
, punk
);
161 static HRESULT WINAPI
BlockingBindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
, DWORD grfBSCF
,
162 DWORD dwSize
, FORMATETC
* pformatetc
, STGMEDIUM
* pstgmed
)
167 static const IBindStatusCallbackVtbl BlockingBindStatusCallbackVtbl
=
169 ProxyBindStatusCallback_QueryInterface
,
170 ProxyBindStatusCallback_AddRef
,
171 ProxyBindStatusCallback_Release
,
172 ProxyBindStatusCallback_OnStartBinding
,
173 ProxyBindStatusCallback_GetPriority
,
174 ProxyBindStatusCallback_OnLowResource
,
175 ProxyBindStatusCallback_OnProgress
,
176 ProxyBindStatusCallback_OnStopBinding
,
177 ProxyBindStatusCallback_GetBindInfo
,
178 BlockingBindStatusCallback_OnDataAvailable
,
179 ProxyBindStatusCallback_OnObjectAvailable
182 static HRESULT WINAPI
AsyncBindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
, DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
184 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
188 hr
= IBindStatusCallback_GetBindInfo(This
->pBSC
, grfBINDF
, pbindinfo
);
190 DWORD size
= pbindinfo
->cbSize
;
191 memset(pbindinfo
, 0, size
);
192 pbindinfo
->cbSize
= size
;
197 *grfBINDF
|= BINDF_PULLDATA
| BINDF_ASYNCHRONOUS
| BINDF_ASYNCSTORAGE
;
202 static const IBindStatusCallbackVtbl AsyncBindStatusCallbackVtbl
=
204 ProxyBindStatusCallback_QueryInterface
,
205 ProxyBindStatusCallback_AddRef
,
206 ProxyBindStatusCallback_Release
,
207 ProxyBindStatusCallback_OnStartBinding
,
208 ProxyBindStatusCallback_GetPriority
,
209 ProxyBindStatusCallback_OnLowResource
,
210 ProxyBindStatusCallback_OnProgress
,
211 ProxyBindStatusCallback_OnStopBinding
,
212 AsyncBindStatusCallback_GetBindInfo
,
213 ProxyBindStatusCallback_OnDataAvailable
,
214 ProxyBindStatusCallback_OnObjectAvailable
217 static HRESULT
URLStartDownload(LPCWSTR szURL
, LPSTREAM
*ppStream
, IBindStatusCallback
*pBSC
)
225 hr
= CreateURLMoniker(NULL
, szURL
, &pMoniker
);
229 hr
= CreateBindCtx(0, &pbc
);
232 IMoniker_Release(pMoniker
);
236 hr
= RegisterBindStatusCallback(pbc
, pBSC
, NULL
, 0);
239 IBindCtx_Release(pbc
);
240 IMoniker_Release(pMoniker
);
244 hr
= IMoniker_BindToStorage(pMoniker
, pbc
, NULL
, &IID_IStream
, (void **)ppStream
);
246 /* BindToStorage returning E_PENDING because it's asynchronous is not an error */
247 if (hr
== E_PENDING
) hr
= S_OK
;
249 IBindCtx_Release(pbc
);
250 IMoniker_Release(pMoniker
);
255 /***********************************************************************
256 * URLOpenBlockingStreamA (URLMON.@)
258 HRESULT WINAPI
URLOpenBlockingStreamA(LPUNKNOWN pCaller
, LPCSTR szURL
,
259 LPSTREAM
*ppStream
, DWORD dwReserved
,
260 LPBINDSTATUSCALLBACK lpfnCB
)
266 TRACE("(%p, %s, %p, 0x%lx, %p)\n", pCaller
, szURL
, ppStream
, dwReserved
, lpfnCB
);
268 if (!szURL
|| !ppStream
)
271 len
= MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, NULL
, 0);
272 szURLW
= malloc(len
* sizeof(WCHAR
));
276 return E_OUTOFMEMORY
;
278 MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, szURLW
, len
);
280 hr
= URLOpenBlockingStreamW(pCaller
, szURLW
, ppStream
, dwReserved
, lpfnCB
);
287 /***********************************************************************
288 * URLOpenBlockingStreamW (URLMON.@)
290 HRESULT WINAPI
URLOpenBlockingStreamW(LPUNKNOWN pCaller
, LPCWSTR szURL
,
291 LPSTREAM
*ppStream
, DWORD dwReserved
,
292 LPBINDSTATUSCALLBACK lpfnCB
)
294 ProxyBindStatusCallback blocking_bsc
;
296 TRACE("(%p, %s, %p, 0x%lx, %p)\n", pCaller
, debugstr_w(szURL
), ppStream
,
299 if (!szURL
|| !ppStream
)
302 blocking_bsc
.IBindStatusCallback_iface
.lpVtbl
= &BlockingBindStatusCallbackVtbl
;
303 blocking_bsc
.pBSC
= lpfnCB
;
305 return URLStartDownload(szURL
, ppStream
, &blocking_bsc
.IBindStatusCallback_iface
);
308 /***********************************************************************
309 * URLOpenStreamA (URLMON.@)
311 HRESULT WINAPI
URLOpenStreamA(LPUNKNOWN pCaller
, LPCSTR szURL
, DWORD dwReserved
,
312 LPBINDSTATUSCALLBACK lpfnCB
)
318 TRACE("(%p, %s, 0x%lx, %p)\n", pCaller
, szURL
, dwReserved
, lpfnCB
);
323 len
= MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, NULL
, 0);
324 szURLW
= malloc(len
* sizeof(WCHAR
));
326 return E_OUTOFMEMORY
;
327 MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, szURLW
, len
);
329 hr
= URLOpenStreamW(pCaller
, szURLW
, dwReserved
, lpfnCB
);
336 /***********************************************************************
337 * URLOpenStreamW (URLMON.@)
339 HRESULT WINAPI
URLOpenStreamW(LPUNKNOWN pCaller
, LPCWSTR szURL
, DWORD dwReserved
,
340 LPBINDSTATUSCALLBACK lpfnCB
)
343 ProxyBindStatusCallback async_bsc
;
346 TRACE("(%p, %s, 0x%lx, %p)\n", pCaller
, debugstr_w(szURL
), dwReserved
,
352 async_bsc
.IBindStatusCallback_iface
.lpVtbl
= &AsyncBindStatusCallbackVtbl
;
353 async_bsc
.pBSC
= lpfnCB
;
355 hr
= URLStartDownload(szURL
, &pStream
, &async_bsc
.IBindStatusCallback_iface
);
356 if (SUCCEEDED(hr
) && pStream
)
357 IStream_Release(pStream
);
362 /***********************************************************************
363 * URLOpenPullStreamW (URLMON.@)
365 HRESULT WINAPI
URLOpenPullStreamW(IUnknown
*caller
, const WCHAR
*url
, DWORD reserved
,
366 IBindStatusCallback
*callback
)
368 FIXME("%p %s %lu %p, stub!\n", caller
, debugstr_w(url
), reserved
, callback
);