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