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"
24 typedef struct ProxyBindStatusCallback
26 IBindStatusCallback IBindStatusCallback_iface
;
28 IBindStatusCallback
*pBSC
;
29 } ProxyBindStatusCallback
;
31 static inline ProxyBindStatusCallback
*impl_from_IBindStatusCallback(IBindStatusCallback
*iface
)
33 return CONTAINING_RECORD(iface
, ProxyBindStatusCallback
, IBindStatusCallback_iface
);
36 static HRESULT WINAPI
ProxyBindStatusCallback_QueryInterface(IBindStatusCallback
*iface
, REFIID riid
, void **ppv
)
38 if (IsEqualGUID(&IID_IBindStatusCallback
, riid
) ||
39 IsEqualGUID(&IID_IUnknown
, riid
))
42 IBindStatusCallback_AddRef(iface
);
50 static ULONG WINAPI
ProxyBindStatusCallback_AddRef(IBindStatusCallback
*iface
)
55 static ULONG WINAPI
ProxyBindStatusCallback_Release(IBindStatusCallback
*iface
)
60 static HRESULT WINAPI
ProxyBindStatusCallback_OnStartBinding(IBindStatusCallback
*iface
, DWORD dwReserved
,
63 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
66 return IBindStatusCallback_OnStartBinding(This
->pBSC
, dwReserved
, pib
);
71 static HRESULT WINAPI
ProxyBindStatusCallback_GetPriority(IBindStatusCallback
*iface
, LONG
*pnPriority
)
73 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
76 return IBindStatusCallback_GetPriority(This
->pBSC
, pnPriority
);
81 static HRESULT WINAPI
ProxyBindStatusCallback_OnLowResource(IBindStatusCallback
*iface
, DWORD reserved
)
83 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
86 return IBindStatusCallback_OnLowResource(This
->pBSC
, reserved
);
91 static HRESULT WINAPI
ProxyBindStatusCallback_OnProgress(IBindStatusCallback
*iface
, ULONG ulProgress
,
92 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
94 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
97 return IBindStatusCallback_OnProgress(This
->pBSC
, ulProgress
,
98 ulProgressMax
, ulStatusCode
,
104 static HRESULT WINAPI
ProxyBindStatusCallback_OnStopBinding(IBindStatusCallback
*iface
, HRESULT hresult
, LPCWSTR szError
)
106 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
109 return IBindStatusCallback_OnStopBinding(This
->pBSC
, hresult
, szError
);
114 static HRESULT WINAPI
ProxyBindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
, DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
116 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
119 return IBindStatusCallback_GetBindInfo(This
->pBSC
, grfBINDF
, pbindinfo
);
124 static HRESULT WINAPI
ProxyBindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
, DWORD grfBSCF
,
125 DWORD dwSize
, FORMATETC
* pformatetc
, STGMEDIUM
* pstgmed
)
127 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
130 return IBindStatusCallback_OnDataAvailable(This
->pBSC
, grfBSCF
, dwSize
,
131 pformatetc
, pstgmed
);
136 static HRESULT WINAPI
ProxyBindStatusCallback_OnObjectAvailable(IBindStatusCallback
*iface
, REFIID riid
, IUnknown
*punk
)
138 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
141 return IBindStatusCallback_OnObjectAvailable(This
->pBSC
, riid
, punk
);
146 static HRESULT WINAPI
BlockingBindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
, DWORD grfBSCF
,
147 DWORD dwSize
, FORMATETC
* pformatetc
, STGMEDIUM
* pstgmed
)
152 static const IBindStatusCallbackVtbl BlockingBindStatusCallbackVtbl
=
154 ProxyBindStatusCallback_QueryInterface
,
155 ProxyBindStatusCallback_AddRef
,
156 ProxyBindStatusCallback_Release
,
157 ProxyBindStatusCallback_OnStartBinding
,
158 ProxyBindStatusCallback_GetPriority
,
159 ProxyBindStatusCallback_OnLowResource
,
160 ProxyBindStatusCallback_OnProgress
,
161 ProxyBindStatusCallback_OnStopBinding
,
162 ProxyBindStatusCallback_GetBindInfo
,
163 BlockingBindStatusCallback_OnDataAvailable
,
164 ProxyBindStatusCallback_OnObjectAvailable
167 static HRESULT WINAPI
AsyncBindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
, DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
169 ProxyBindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
170 HRESULT hr
= IBindStatusCallback_GetBindInfo(This
->pBSC
, grfBINDF
, pbindinfo
);
171 *grfBINDF
|= BINDF_PULLDATA
| BINDF_ASYNCHRONOUS
| BINDF_ASYNCSTORAGE
;
175 static const IBindStatusCallbackVtbl AsyncBindStatusCallbackVtbl
=
177 ProxyBindStatusCallback_QueryInterface
,
178 ProxyBindStatusCallback_AddRef
,
179 ProxyBindStatusCallback_Release
,
180 ProxyBindStatusCallback_OnStartBinding
,
181 ProxyBindStatusCallback_GetPriority
,
182 ProxyBindStatusCallback_OnLowResource
,
183 ProxyBindStatusCallback_OnProgress
,
184 ProxyBindStatusCallback_OnStopBinding
,
185 AsyncBindStatusCallback_GetBindInfo
,
186 ProxyBindStatusCallback_OnDataAvailable
,
187 ProxyBindStatusCallback_OnObjectAvailable
190 static HRESULT
URLStartDownload(LPCWSTR szURL
, LPSTREAM
*ppStream
, IBindStatusCallback
*pBSC
)
198 hr
= CreateURLMoniker(NULL
, szURL
, &pMoniker
);
202 hr
= CreateBindCtx(0, &pbc
);
205 IMoniker_Release(pMoniker
);
209 hr
= RegisterBindStatusCallback(pbc
, pBSC
, NULL
, 0);
212 IBindCtx_Release(pbc
);
213 IMoniker_Release(pMoniker
);
217 hr
= IMoniker_BindToStorage(pMoniker
, pbc
, NULL
, &IID_IStream
, (void **)ppStream
);
219 /* BindToStorage returning E_PENDING because it's asynchronous is not an error */
220 if (hr
== E_PENDING
) hr
= S_OK
;
222 IBindCtx_Release(pbc
);
223 IMoniker_Release(pMoniker
);
228 /***********************************************************************
229 * URLOpenBlockingStreamA (URLMON.@)
231 HRESULT WINAPI
URLOpenBlockingStreamA(LPUNKNOWN pCaller
, LPCSTR szURL
,
232 LPSTREAM
*ppStream
, DWORD dwReserved
,
233 LPBINDSTATUSCALLBACK lpfnCB
)
239 TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller
, szURL
, ppStream
, dwReserved
, lpfnCB
);
241 if (!szURL
|| !ppStream
)
244 len
= MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, NULL
, 0);
245 szURLW
= heap_alloc(len
* sizeof(WCHAR
));
249 return E_OUTOFMEMORY
;
251 MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, szURLW
, len
);
253 hr
= URLOpenBlockingStreamW(pCaller
, szURLW
, ppStream
, dwReserved
, lpfnCB
);
260 /***********************************************************************
261 * URLOpenBlockingStreamW (URLMON.@)
263 HRESULT WINAPI
URLOpenBlockingStreamW(LPUNKNOWN pCaller
, LPCWSTR szURL
,
264 LPSTREAM
*ppStream
, DWORD dwReserved
,
265 LPBINDSTATUSCALLBACK lpfnCB
)
267 ProxyBindStatusCallback blocking_bsc
;
269 TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller
, debugstr_w(szURL
), ppStream
,
272 if (!szURL
|| !ppStream
)
275 blocking_bsc
.IBindStatusCallback_iface
.lpVtbl
= &BlockingBindStatusCallbackVtbl
;
276 blocking_bsc
.pBSC
= lpfnCB
;
278 return URLStartDownload(szURL
, ppStream
, &blocking_bsc
.IBindStatusCallback_iface
);
281 /***********************************************************************
282 * URLOpenStreamA (URLMON.@)
284 HRESULT WINAPI
URLOpenStreamA(LPUNKNOWN pCaller
, LPCSTR szURL
, DWORD dwReserved
,
285 LPBINDSTATUSCALLBACK lpfnCB
)
291 TRACE("(%p, %s, 0x%x, %p)\n", pCaller
, szURL
, dwReserved
, lpfnCB
);
296 len
= MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, NULL
, 0);
297 szURLW
= heap_alloc(len
* sizeof(WCHAR
));
299 return E_OUTOFMEMORY
;
300 MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, szURLW
, len
);
302 hr
= URLOpenStreamW(pCaller
, szURLW
, dwReserved
, lpfnCB
);
309 /***********************************************************************
310 * URLOpenStreamW (URLMON.@)
312 HRESULT WINAPI
URLOpenStreamW(LPUNKNOWN pCaller
, LPCWSTR szURL
, DWORD dwReserved
,
313 LPBINDSTATUSCALLBACK lpfnCB
)
316 ProxyBindStatusCallback async_bsc
;
319 TRACE("(%p, %s, 0x%x, %p)\n", pCaller
, debugstr_w(szURL
), dwReserved
,
325 async_bsc
.IBindStatusCallback_iface
.lpVtbl
= &AsyncBindStatusCallbackVtbl
;
326 async_bsc
.pBSC
= lpfnCB
;
328 hr
= URLStartDownload(szURL
, &pStream
, &async_bsc
.IBindStatusCallback_iface
);
329 if (SUCCEEDED(hr
) && pStream
)
330 IStream_Release(pStream
);