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
= 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_uri(const WCHAR
*url
, IUri
**uri
)
247 WCHAR fileUrl
[INTERNET_MAX_URL_LENGTH
];
249 TRACE("%s\n", debugstr_w(url
));
251 if (!PathIsURLW(url
))
253 WCHAR fullpath
[MAX_PATH
];
254 DWORD needed
= ARRAY_SIZE(fileUrl
);
256 lstrcpynW(fileUrl
, url
, ARRAY_SIZE(fileUrl
));
257 UrlUnescapeW(fileUrl
, NULL
, NULL
, URL_UNESCAPE_INPLACE
);
259 if (!PathSearchAndQualifyW(fileUrl
, fullpath
, ARRAY_SIZE(fullpath
)))
261 WARN("can't find path\n");
265 if (FAILED(UrlApplySchemeW(fullpath
, fileUrl
, &needed
, URL_APPLY_GUESSSCHEME
| URL_APPLY_GUESSFILE
|
268 ERR("Failed to apply url scheme.\n");
274 return CreateUri(url
, Uri_CREATE_ALLOW_RELATIVE
| Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME
, 0, uri
);
277 HRESULT
create_moniker_from_url(LPCWSTR url
, IMoniker
**mon
)
282 TRACE("%s\n", debugstr_w(url
));
284 if (FAILED(hr
= create_uri(url
, &uri
)))
287 hr
= CreateURLMonikerEx2(NULL
, uri
, mon
, 0);
292 HRESULT
bind_url(IMoniker
*mon
, HRESULT (*onDataAvailable
)(void*,char*,DWORD
),
293 void *obj
, bsc_t
**ret
)
301 hr
= CreateBindCtx(0, &pbc
);
305 bsc
= heap_alloc(sizeof(bsc_t
));
307 bsc
->IBindStatusCallback_iface
.lpVtbl
= &bsc_vtbl
;
310 bsc
->onDataAvailable
= onDataAvailable
;
312 bsc
->memstream
= NULL
;
315 hr
= RegisterBindStatusCallback(pbc
, &bsc
->IBindStatusCallback_iface
, NULL
, 0);
319 hr
= IMoniker_BindToStorage(mon
, pbc
, NULL
, &IID_IStream
, (LPVOID
*)&stream
);
321 IStream_Release(stream
);
322 IBindCtx_Release(pbc
);
327 IBindStatusCallback_Release(&bsc
->IBindStatusCallback_iface
);
335 HRESULT
detach_bsc(bsc_t
*bsc
)
340 IBinding_Abort(bsc
->binding
);
344 IBindStatusCallback_Release(&bsc
->IBindStatusCallback_iface
);