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
26 # include <libxml/parser.h>
27 # include <libxml/xmlerror.h>
40 #include "wine/debug.h"
42 #include "msxml_private.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
47 IBindStatusCallback IBindStatusCallback_iface;
52 HRESULT (*onDataAvailable)(void*,char*,DWORD);
59 static inline bsc_t *impl_from_IBindStatusCallback( IBindStatusCallback *iface )
61 return CONTAINING_RECORD(iface, bsc_t, IBindStatusCallback_iface);
64 static HRESULT WINAPI bsc_QueryInterface(
65 IBindStatusCallback *iface,
69 if (IsEqualGUID(riid, &IID_IUnknown) ||
70 IsEqualGUID(riid, &IID_IBindStatusCallback))
72 IBindStatusCallback_AddRef( iface );
77 TRACE("interface %s not implemented\n", debugstr_guid(riid));
82 static ULONG WINAPI bsc_AddRef(
83 IBindStatusCallback *iface )
85 bsc_t *This = impl_from_IBindStatusCallback(iface);
86 LONG ref = InterlockedIncrement(&This->ref);
88 TRACE("(%p) ref=%d\n", This, ref);
93 static ULONG WINAPI bsc_Release(
94 IBindStatusCallback *iface )
96 bsc_t *This = impl_from_IBindStatusCallback(iface);
97 LONG ref = InterlockedDecrement(&This->ref);
99 TRACE("(%p) ref=%d\n", This, ref);
102 if (This->binding) IBinding_Release(This->binding);
103 if (This->memstream) IStream_Release(This->memstream);
110 static HRESULT WINAPI bsc_OnStartBinding(
111 IBindStatusCallback* iface,
115 bsc_t *This = impl_from_IBindStatusCallback(iface);
118 TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
121 IBinding_AddRef(pib);
123 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream);
130 static HRESULT WINAPI bsc_GetPriority(
131 IBindStatusCallback* iface,
137 static HRESULT WINAPI bsc_OnLowResource(
138 IBindStatusCallback* iface,
144 static HRESULT WINAPI bsc_OnProgress(
145 IBindStatusCallback* iface,
149 LPCWSTR szStatusText)
154 static HRESULT WINAPI bsc_OnStopBinding(
155 IBindStatusCallback* iface,
159 bsc_t *This = impl_from_IBindStatusCallback(iface);
162 TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
165 IBinding_Release(This->binding);
166 This->binding = NULL;
169 if(This->obj && SUCCEEDED(hresult)) {
171 hr = GetHGlobalFromStream(This->memstream, &hglobal);
174 DWORD len = GlobalSize(hglobal);
175 char *ptr = GlobalLock(hglobal);
177 This->hres = hr = This->onDataAvailable(This->obj, ptr, len);
179 GlobalUnlock(hglobal);
186 static HRESULT WINAPI bsc_GetBindInfo(
187 IBindStatusCallback* iface,
191 *grfBINDF = BINDF_GETNEWESTVERSION|BINDF_PULLDATA|BINDF_RESYNCHRONIZE|BINDF_PRAGMA_NO_CACHE;
196 static HRESULT WINAPI bsc_OnDataAvailable(
197 IBindStatusCallback* iface,
200 FORMATETC* pformatetc,
203 bsc_t *This = impl_from_IBindStatusCallback(iface);
208 TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
212 hr = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read);
216 hr = IStream_Write(This->memstream, buf, read, &written);
217 } while(SUCCEEDED(hr) && written != 0 && read != 0);
222 static HRESULT WINAPI bsc_OnObjectAvailable(
223 IBindStatusCallback* iface,
230 static const struct IBindStatusCallbackVtbl bsc_vtbl =
242 bsc_OnObjectAvailable
245 HRESULT create_moniker_from_url(LPCWSTR url, IMoniker **mon)
247 WCHAR fileUrl[INTERNET_MAX_URL_LENGTH];
249 TRACE("%s\n", debugstr_w(url));
253 WCHAR fullpath[MAX_PATH];
254 DWORD needed = sizeof(fileUrl)/sizeof(WCHAR);
256 if(!PathSearchAndQualifyW(url, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
258 WARN("can't find path\n");
262 if(FAILED(UrlCreateFromPathW(url, fileUrl, &needed, 0)))
264 ERR("can't create url from path\n");
270 return CreateURLMonikerEx(NULL, url, mon, 0);
273 HRESULT bind_url(IMoniker *mon, HRESULT (*onDataAvailable)(void*,char*,DWORD),
274 void *obj, bsc_t **ret)
282 hr = CreateBindCtx(0, &pbc);
286 bsc = heap_alloc(sizeof(bsc_t));
288 bsc->IBindStatusCallback_iface.lpVtbl = &bsc_vtbl;
291 bsc->onDataAvailable = onDataAvailable;
293 bsc->memstream = NULL;
296 hr = RegisterBindStatusCallback(pbc, &bsc->IBindStatusCallback_iface, NULL, 0);
300 hr = IMoniker_BindToStorage(mon, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
302 IStream_Release(stream);
303 IBindCtx_Release(pbc);
308 IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface);
316 HRESULT detach_bsc(bsc_t *bsc)
321 IBinding_Abort(bsc->binding);
325 IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface);