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
);