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
);
58 static inline bsc_t
*impl_from_IBindStatusCallback( IBindStatusCallback
*iface
)
60 return CONTAINING_RECORD(iface
, bsc_t
, IBindStatusCallback_iface
);
63 static HRESULT WINAPI
bsc_QueryInterface(
64 IBindStatusCallback
*iface
,
68 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
69 IsEqualGUID(riid
, &IID_IBindStatusCallback
))
71 IBindStatusCallback_AddRef( iface
);
76 TRACE("interface %s not implemented\n", debugstr_guid(riid
));
81 static ULONG WINAPI
bsc_AddRef(
82 IBindStatusCallback
*iface
)
84 bsc_t
*This
= impl_from_IBindStatusCallback(iface
);
85 LONG ref
= InterlockedIncrement(&This
->ref
);
87 TRACE("(%p) ref=%d\n", This
, ref
);
92 static ULONG WINAPI
bsc_Release(
93 IBindStatusCallback
*iface
)
95 bsc_t
*This
= impl_from_IBindStatusCallback(iface
);
96 LONG ref
= InterlockedDecrement(&This
->ref
);
98 TRACE("(%p) ref=%d\n", This
, ref
);
101 if (This
->binding
) IBinding_Release(This
->binding
);
102 if (This
->memstream
) IStream_Release(This
->memstream
);
109 static HRESULT WINAPI
bsc_OnStartBinding(
110 IBindStatusCallback
* iface
,
114 bsc_t
*This
= impl_from_IBindStatusCallback(iface
);
117 TRACE("(%p)->(%x %p)\n", This
, dwReserved
, pib
);
120 IBinding_AddRef(pib
);
122 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->memstream
);
129 static HRESULT WINAPI
bsc_GetPriority(
130 IBindStatusCallback
* iface
,
136 static HRESULT WINAPI
bsc_OnLowResource(
137 IBindStatusCallback
* iface
,
143 static HRESULT WINAPI
bsc_OnProgress(
144 IBindStatusCallback
* iface
,
148 LPCWSTR szStatusText
)
153 static HRESULT WINAPI
bsc_OnStopBinding(
154 IBindStatusCallback
* iface
,
158 bsc_t
*This
= impl_from_IBindStatusCallback(iface
);
161 TRACE("(%p)->(%08x %s)\n", This
, hresult
, debugstr_w(szError
));
164 IBinding_Release(This
->binding
);
165 This
->binding
= NULL
;
168 if(This
->obj
&& SUCCEEDED(hresult
)) {
170 hr
= GetHGlobalFromStream(This
->memstream
, &hglobal
);
173 DWORD len
= GlobalSize(hglobal
);
174 char *ptr
= GlobalLock(hglobal
);
176 hr
= This
->onDataAvailable(This
->obj
, ptr
, len
);
178 GlobalUnlock(hglobal
);
185 static HRESULT WINAPI
bsc_GetBindInfo(
186 IBindStatusCallback
* iface
,
190 *grfBINDF
= BINDF_GETNEWESTVERSION
|BINDF_PULLDATA
|BINDF_RESYNCHRONIZE
|BINDF_PRAGMA_NO_CACHE
;
195 static HRESULT WINAPI
bsc_OnDataAvailable(
196 IBindStatusCallback
* iface
,
199 FORMATETC
* pformatetc
,
202 bsc_t
*This
= impl_from_IBindStatusCallback(iface
);
207 TRACE("(%p)->(%x %d %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
211 hr
= IStream_Read(pstgmed
->u
.pstm
, buf
, sizeof(buf
), &read
);
215 hr
= IStream_Write(This
->memstream
, buf
, read
, &written
);
216 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
221 static HRESULT WINAPI
bsc_OnObjectAvailable(
222 IBindStatusCallback
* iface
,
229 static const struct IBindStatusCallbackVtbl bsc_vtbl
=
241 bsc_OnObjectAvailable
244 HRESULT
bind_url(LPCWSTR url
, HRESULT (*onDataAvailable
)(void*,char*,DWORD
), void *obj
, bsc_t
**ret
)
246 WCHAR fileUrl
[INTERNET_MAX_URL_LENGTH
];
251 TRACE("%s\n", debugstr_w(url
));
255 WCHAR fullpath
[MAX_PATH
];
256 DWORD needed
= sizeof(fileUrl
)/sizeof(WCHAR
);
258 if(!PathSearchAndQualifyW(url
, fullpath
, sizeof(fullpath
)/sizeof(WCHAR
)))
260 WARN("can't find path\n");
264 if(FAILED(UrlCreateFromPathW(url
, fileUrl
, &needed
, 0)))
266 ERR("can't create url from path\n");
272 hr
= CreateBindCtx(0, &pbc
);
276 bsc
= heap_alloc(sizeof(bsc_t
));
278 bsc
->IBindStatusCallback_iface
.lpVtbl
= &bsc_vtbl
;
281 bsc
->onDataAvailable
= onDataAvailable
;
283 bsc
->memstream
= NULL
;
285 hr
= RegisterBindStatusCallback(pbc
, &bsc
->IBindStatusCallback_iface
, NULL
, 0);
290 hr
= CreateURLMoniker(NULL
, url
, &moniker
);
294 hr
= IMoniker_BindToStorage(moniker
, pbc
, NULL
, &IID_IStream
, (LPVOID
*)&stream
);
295 IMoniker_Release(moniker
);
297 IStream_Release(stream
);
299 IBindCtx_Release(pbc
);
304 IBindStatusCallback_Release(&bsc
->IBindStatusCallback_iface
);
312 void detach_bsc(bsc_t
*bsc
)
315 IBinding_Abort(bsc
->binding
);
318 IBindStatusCallback_Release(&bsc
->IBindStatusCallback_iface
);