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 const IBindStatusCallbackVtbl
*lpVtbl
;
37 IBindStatusCallback
*pBSC
;
38 } ProxyBindStatusCallback
;
40 static HRESULT WINAPI
ProxyBindStatusCallback_QueryInterface(IBindStatusCallback
*iface
, REFIID riid
, void **ppv
)
42 if (IsEqualGUID(&IID_IBindStatusCallback
, riid
) ||
43 IsEqualGUID(&IID_IUnknown
, riid
))
46 IUnknown_AddRef(iface
);
54 static ULONG WINAPI
ProxyBindStatusCallback_AddRef(IBindStatusCallback
*iface
)
59 static ULONG WINAPI
ProxyBindStatusCallback_Release(IBindStatusCallback
*iface
)
64 static HRESULT WINAPI
ProxyBindStatusCallback_OnStartBinding(IBindStatusCallback
*iface
, DWORD dwReserved
,
67 ProxyBindStatusCallback
*This
= (ProxyBindStatusCallback
*)iface
;
70 return IBindStatusCallback_OnStartBinding(This
->pBSC
, dwReserved
, pib
);
75 static HRESULT WINAPI
ProxyBindStatusCallback_GetPriority(IBindStatusCallback
*iface
, LONG
*pnPriority
)
77 ProxyBindStatusCallback
*This
= (ProxyBindStatusCallback
*)iface
;
80 return IBindStatusCallback_GetPriority(This
->pBSC
, pnPriority
);
85 static HRESULT WINAPI
ProxyBindStatusCallback_OnLowResource(IBindStatusCallback
*iface
, DWORD reserved
)
87 ProxyBindStatusCallback
*This
= (ProxyBindStatusCallback
*)iface
;
90 return IBindStatusCallback_OnLowResource(This
->pBSC
, reserved
);
95 static HRESULT WINAPI
ProxyBindStatusCallback_OnProgress(IBindStatusCallback
*iface
, ULONG ulProgress
,
96 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
98 ProxyBindStatusCallback
*This
= (ProxyBindStatusCallback
*)iface
;
101 return IBindStatusCallback_OnProgress(This
->pBSC
, ulProgress
,
102 ulProgressMax
, ulStatusCode
,
108 static HRESULT WINAPI
ProxyBindStatusCallback_OnStopBinding(IBindStatusCallback
*iface
, HRESULT hresult
, LPCWSTR szError
)
110 ProxyBindStatusCallback
*This
= (ProxyBindStatusCallback
*)iface
;
113 return IBindStatusCallback_OnStopBinding(This
->pBSC
, hresult
, szError
);
118 static HRESULT WINAPI
ProxyBindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
, DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
120 ProxyBindStatusCallback
*This
= (ProxyBindStatusCallback
*)iface
;
123 return IBindStatusCallback_GetBindInfo(This
->pBSC
, grfBINDF
, pbindinfo
);
128 static HRESULT WINAPI
ProxyBindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
, DWORD grfBSCF
,
129 DWORD dwSize
, FORMATETC
* pformatetc
, STGMEDIUM
* pstgmed
)
131 ProxyBindStatusCallback
*This
= (ProxyBindStatusCallback
*)iface
;
134 return IBindStatusCallback_OnDataAvailable(This
->pBSC
, grfBSCF
, dwSize
,
135 pformatetc
, pstgmed
);
140 static HRESULT WINAPI
ProxyBindStatusCallback_OnObjectAvailable(IBindStatusCallback
*iface
, REFIID riid
, IUnknown
*punk
)
142 ProxyBindStatusCallback
*This
= (ProxyBindStatusCallback
*)iface
;
145 return IBindStatusCallback_OnObjectAvailable(This
->pBSC
, riid
, punk
);
150 static HRESULT WINAPI
BlockingBindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
, DWORD grfBSCF
,
151 DWORD dwSize
, FORMATETC
* pformatetc
, STGMEDIUM
* pstgmed
)
156 static const IBindStatusCallbackVtbl BlockingBindStatusCallbackVtbl
=
158 ProxyBindStatusCallback_QueryInterface
,
159 ProxyBindStatusCallback_AddRef
,
160 ProxyBindStatusCallback_Release
,
161 ProxyBindStatusCallback_OnStartBinding
,
162 ProxyBindStatusCallback_GetPriority
,
163 ProxyBindStatusCallback_OnLowResource
,
164 ProxyBindStatusCallback_OnProgress
,
165 ProxyBindStatusCallback_OnStopBinding
,
166 ProxyBindStatusCallback_GetBindInfo
,
167 BlockingBindStatusCallback_OnDataAvailable
,
168 ProxyBindStatusCallback_OnObjectAvailable
171 static HRESULT WINAPI
AsyncBindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
, DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
173 ProxyBindStatusCallback
*This
= (ProxyBindStatusCallback
*)iface
;
174 HRESULT hr
= IBindStatusCallback_GetBindInfo(This
->pBSC
, grfBINDF
, pbindinfo
);
175 *grfBINDF
|= BINDF_PULLDATA
| BINDF_ASYNCHRONOUS
| BINDF_ASYNCSTORAGE
;
179 static const IBindStatusCallbackVtbl AsyncBindStatusCallbackVtbl
=
181 ProxyBindStatusCallback_QueryInterface
,
182 ProxyBindStatusCallback_AddRef
,
183 ProxyBindStatusCallback_Release
,
184 ProxyBindStatusCallback_OnStartBinding
,
185 ProxyBindStatusCallback_GetPriority
,
186 ProxyBindStatusCallback_OnLowResource
,
187 ProxyBindStatusCallback_OnProgress
,
188 ProxyBindStatusCallback_OnStopBinding
,
189 AsyncBindStatusCallback_GetBindInfo
,
190 ProxyBindStatusCallback_OnDataAvailable
,
191 ProxyBindStatusCallback_OnObjectAvailable
194 static HRESULT
URLStartDownload(LPCWSTR szURL
, LPSTREAM
*ppStream
, IBindStatusCallback
*pBSC
)
202 hr
= CreateURLMoniker(NULL
, szURL
, &pMoniker
);
206 hr
= CreateBindCtx(0, &pbc
);
209 IMoniker_Release(pMoniker
);
213 hr
= RegisterBindStatusCallback(pbc
, pBSC
, NULL
, 0);
216 IBindCtx_Release(pbc
);
217 IMoniker_Release(pMoniker
);
221 hr
= IMoniker_BindToStorage(pMoniker
, pbc
, NULL
, &IID_IStream
, (void **)ppStream
);
223 /* BindToStorage returning E_PENDING because it's asynchronous is not an error */
224 if (hr
== E_PENDING
) hr
= S_OK
;
226 IBindCtx_Release(pbc
);
227 IMoniker_Release(pMoniker
);
232 /***********************************************************************
233 * URLOpenBlockingStreamA (URLMON.@)
235 HRESULT WINAPI
URLOpenBlockingStreamA(LPUNKNOWN pCaller
, LPCSTR szURL
,
236 LPSTREAM
*ppStream
, DWORD dwReserved
,
237 LPBINDSTATUSCALLBACK lpfnCB
)
243 TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller
, szURL
, ppStream
, dwReserved
, lpfnCB
);
245 if (!szURL
|| !ppStream
)
248 len
= MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, NULL
, 0);
249 szURLW
= heap_alloc(len
* sizeof(WCHAR
));
253 return E_OUTOFMEMORY
;
255 MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, szURLW
, len
);
257 hr
= URLOpenBlockingStreamW(pCaller
, szURLW
, ppStream
, dwReserved
, lpfnCB
);
264 /***********************************************************************
265 * URLOpenBlockingStreamW (URLMON.@)
267 HRESULT WINAPI
URLOpenBlockingStreamW(LPUNKNOWN pCaller
, LPCWSTR szURL
,
268 LPSTREAM
*ppStream
, DWORD dwReserved
,
269 LPBINDSTATUSCALLBACK lpfnCB
)
271 ProxyBindStatusCallback blocking_bsc
;
273 TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller
, debugstr_w(szURL
), ppStream
,
276 if (!szURL
|| !ppStream
)
279 blocking_bsc
.lpVtbl
= &BlockingBindStatusCallbackVtbl
;
280 blocking_bsc
.pBSC
= lpfnCB
;
282 return URLStartDownload(szURL
, ppStream
, (IBindStatusCallback
*)&blocking_bsc
);
285 /***********************************************************************
286 * URLOpenStreamA (URLMON.@)
288 HRESULT WINAPI
URLOpenStreamA(LPUNKNOWN pCaller
, LPCSTR szURL
, DWORD dwReserved
,
289 LPBINDSTATUSCALLBACK lpfnCB
)
295 TRACE("(%p, %s, 0x%x, %p)\n", pCaller
, szURL
, dwReserved
, lpfnCB
);
300 len
= MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, NULL
, 0);
301 szURLW
= heap_alloc(len
* sizeof(WCHAR
));
303 return E_OUTOFMEMORY
;
304 MultiByteToWideChar(CP_ACP
, 0, szURL
, -1, szURLW
, len
);
306 hr
= URLOpenStreamW(pCaller
, szURLW
, dwReserved
, lpfnCB
);
313 /***********************************************************************
314 * URLOpenStreamW (URLMON.@)
316 HRESULT WINAPI
URLOpenStreamW(LPUNKNOWN pCaller
, LPCWSTR szURL
, DWORD dwReserved
,
317 LPBINDSTATUSCALLBACK lpfnCB
)
320 ProxyBindStatusCallback async_bsc
;
323 TRACE("(%p, %s, 0x%x, %p)\n", pCaller
, debugstr_w(szURL
), dwReserved
,
329 async_bsc
.lpVtbl
= &AsyncBindStatusCallbackVtbl
;
330 async_bsc
.pBSC
= lpfnCB
;
332 hr
= URLStartDownload(szURL
, &pStream
, (IBindStatusCallback
*)&async_bsc
);
333 if (SUCCEEDED(hr
) && pStream
)
334 IStream_Release(pStream
);