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 TRACE("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
);
96 if (This
->binding
) IBinding_Release(This
->binding
);
97 if (This
->memstream
) IStream_Release(This
->memstream
);
104 static HRESULT WINAPI
bsc_OnStartBinding(
105 IBindStatusCallback
* iface
,
109 bsc_t
*This
= impl_from_IBindStatusCallback(iface
);
112 TRACE("(%p)->(%x %p)\n", This
, dwReserved
, pib
);
115 IBinding_AddRef(pib
);
117 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->memstream
);
124 static HRESULT WINAPI
bsc_GetPriority(
125 IBindStatusCallback
* iface
,
131 static HRESULT WINAPI
bsc_OnLowResource(
132 IBindStatusCallback
* iface
,
138 static HRESULT WINAPI
bsc_OnProgress(
139 IBindStatusCallback
* iface
,
143 LPCWSTR szStatusText
)
148 static HRESULT WINAPI
bsc_OnStopBinding(
149 IBindStatusCallback
* iface
,
153 bsc_t
*This
= impl_from_IBindStatusCallback(iface
);
156 TRACE("(%p)->(%08x %s)\n", This
, hresult
, debugstr_w(szError
));
159 IBinding_Release(This
->binding
);
160 This
->binding
= NULL
;
163 if(This
->obj
&& SUCCEEDED(hresult
)) {
165 hr
= GetHGlobalFromStream(This
->memstream
, &hglobal
);
168 DWORD len
= GlobalSize(hglobal
);
169 char *ptr
= GlobalLock(hglobal
);
171 hr
= This
->onDataAvailable(This
->obj
, ptr
, len
);
173 GlobalUnlock(hglobal
);
180 static HRESULT WINAPI
bsc_GetBindInfo(
181 IBindStatusCallback
* iface
,
185 *grfBINDF
= BINDF_GETNEWESTVERSION
|BINDF_PULLDATA
|BINDF_RESYNCHRONIZE
|BINDF_PRAGMA_NO_CACHE
;
190 static HRESULT WINAPI
bsc_OnDataAvailable(
191 IBindStatusCallback
* iface
,
194 FORMATETC
* pformatetc
,
197 bsc_t
*This
= impl_from_IBindStatusCallback(iface
);
202 TRACE("(%p)->(%x %d %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
206 hr
= IStream_Read(pstgmed
->u
.pstm
, buf
, sizeof(buf
), &read
);
210 hr
= IStream_Write(This
->memstream
, buf
, read
, &written
);
211 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
216 static HRESULT WINAPI
bsc_OnObjectAvailable(
217 IBindStatusCallback
* iface
,
224 static const struct IBindStatusCallbackVtbl bsc_vtbl
=
236 bsc_OnObjectAvailable
239 HRESULT
bind_url(LPCWSTR url
, HRESULT (*onDataAvailable
)(void*,char*,DWORD
), void *obj
, bsc_t
**ret
)
241 WCHAR fileUrl
[INTERNET_MAX_URL_LENGTH
];
246 TRACE("%s\n", debugstr_w(url
));
250 WCHAR fullpath
[MAX_PATH
];
251 DWORD needed
= sizeof(fileUrl
)/sizeof(WCHAR
);
253 if(!PathSearchAndQualifyW(url
, fullpath
, sizeof(fullpath
)/sizeof(WCHAR
)))
255 WARN("can't find path\n");
259 if(FAILED(UrlCreateFromPathW(url
, fileUrl
, &needed
, 0)))
261 ERR("can't create url from path\n");
267 hr
= CreateBindCtx(0, &pbc
);
271 bsc
= heap_alloc(sizeof(bsc_t
));
273 bsc
->lpVtbl
= &bsc_vtbl
;
276 bsc
->onDataAvailable
= onDataAvailable
;
278 bsc
->memstream
= NULL
;
280 hr
= RegisterBindStatusCallback(pbc
, (IBindStatusCallback
*)&bsc
->lpVtbl
, NULL
, 0);
285 hr
= CreateURLMoniker(NULL
, url
, &moniker
);
289 hr
= IMoniker_BindToStorage(moniker
, pbc
, NULL
, &IID_IStream
, (LPVOID
*)&stream
);
290 IMoniker_Release(moniker
);
292 IStream_Release(stream
);
294 IBindCtx_Release(pbc
);
299 IBindStatusCallback_Release((IBindStatusCallback
*)&bsc
->lpVtbl
);
307 void detach_bsc(bsc_t
*bsc
)
310 IBinding_Abort(bsc
->binding
);
313 IBindStatusCallback_Release((IBindStatusCallback
*)&bsc
->lpVtbl
);