2 * Copyright 2008 Piotr Caban
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define NONAMELESSUNION
36 #include "wine/debug.h"
38 #include "msxml_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
43 const struct IBindStatusCallbackVtbl *lpVtbl;
48 HRESULT (*onDataAvailable)(void*,char*,DWORD);
54 static inline bsc_t *impl_from_IBindStatusCallback( IBindStatusCallback *iface )
56 return (bsc_t *)((char*)iface - FIELD_OFFSET(bsc_t, lpVtbl));
59 static HRESULT WINAPI bsc_QueryInterface(
60 IBindStatusCallback *iface,
64 if (IsEqualGUID(riid, &IID_IUnknown) ||
65 IsEqualGUID(riid, &IID_IBindStatusCallback))
67 IBindStatusCallback_AddRef( iface );
72 FIXME("interface %s not implemented\n", debugstr_guid(riid));
76 static ULONG WINAPI bsc_AddRef(
77 IBindStatusCallback *iface )
79 bsc_t *This = impl_from_IBindStatusCallback(iface);
80 LONG ref = InterlockedIncrement(&This->ref);
82 TRACE("(%p) ref=%d\n", This, ref);
87 static ULONG WINAPI bsc_Release(
88 IBindStatusCallback *iface )
90 bsc_t *This = impl_from_IBindStatusCallback(iface);
91 LONG ref = InterlockedDecrement(&This->ref);
93 TRACE("(%p) ref=%d\n", This, ref);
97 IBinding_Release(This->binding);
99 IStream_Release(This->memstream);
100 HeapFree(GetProcessHeap(), 0, This);
106 static HRESULT WINAPI bsc_OnStartBinding(
107 IBindStatusCallback* iface,
111 bsc_t *This = impl_from_IBindStatusCallback(iface);
114 TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
117 IBindStatusCallback_AddRef(pib);
119 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream);
126 static HRESULT WINAPI bsc_GetPriority(
127 IBindStatusCallback* iface,
133 static HRESULT WINAPI bsc_OnLowResource(
134 IBindStatusCallback* iface,
140 static HRESULT WINAPI bsc_OnProgress(
141 IBindStatusCallback* iface,
145 LPCWSTR szStatusText)
150 static HRESULT WINAPI bsc_OnStopBinding(
151 IBindStatusCallback* iface,
155 bsc_t *This = impl_from_IBindStatusCallback(iface);
158 TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
161 IBinding_Release(This->binding);
162 This->binding = NULL;
165 if(This->obj && SUCCEEDED(hresult)) {
167 hr = GetHGlobalFromStream(This->memstream, &hglobal);
170 DWORD len = GlobalSize(hglobal);
171 char *ptr = GlobalLock(hglobal);
173 hr = This->onDataAvailable(This->obj, ptr, len);
175 GlobalUnlock(hglobal);
182 static HRESULT WINAPI bsc_GetBindInfo(
183 IBindStatusCallback* iface,
187 *grfBINDF = BINDF_GETNEWESTVERSION|BINDF_PULLDATA|BINDF_RESYNCHRONIZE|BINDF_PRAGMA_NO_CACHE;
192 static HRESULT WINAPI bsc_OnDataAvailable(
193 IBindStatusCallback* iface,
196 FORMATETC* pformatetc,
199 bsc_t *This = impl_from_IBindStatusCallback(iface);
204 TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
208 hr = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read);
212 hr = IStream_Write(This->memstream, buf, read, &written);
213 } while(SUCCEEDED(hr) && written != 0 && read != 0);
218 static HRESULT WINAPI bsc_OnObjectAvailable(
219 IBindStatusCallback* iface,
226 static const struct IBindStatusCallbackVtbl bsc_vtbl =
238 bsc_OnObjectAvailable
241 HRESULT bind_url(LPCWSTR url, HRESULT (*onDataAvailable)(void*,char*,DWORD), void *obj, bsc_t **ret)
243 WCHAR fileUrl[INTERNET_MAX_URL_LENGTH];
248 TRACE("%s\n", debugstr_w(url));
252 WCHAR fullpath[MAX_PATH];
253 DWORD needed = sizeof(fileUrl)/sizeof(WCHAR);
255 if(!PathSearchAndQualifyW(url, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
257 WARN("can't find path\n");
261 if(FAILED(UrlCreateFromPathW(url, fileUrl, &needed, 0)))
263 ERR("can't create url from path\n");
269 hr = CreateBindCtx(0, &pbc);
273 bsc = HeapAlloc(GetProcessHeap(), 0, sizeof(bsc_t));
275 bsc->lpVtbl = &bsc_vtbl;
278 bsc->onDataAvailable = onDataAvailable;
280 bsc->memstream = NULL;
282 hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&bsc->lpVtbl, NULL, 0);
287 hr = CreateURLMoniker(NULL, url, &moniker);
291 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
292 IMoniker_Release(moniker);
294 IStream_Release(stream);
296 IBindCtx_Release(pbc);
303 void detach_bsc(bsc_t *bsc)
306 IBinding_Abort(bsc->binding);
309 IBindStatusCallback_Release((IBindStatusCallback*)&bsc->lpVtbl);