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
33 #include "wine/debug.h"
35 #include "msxml_dispex.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
40 IBindStatusCallback IBindStatusCallback_iface
;
45 HRESULT (*onDataAvailable
)(void*,char*,DWORD
);
52 static inline bsc_t
*impl_from_IBindStatusCallback( IBindStatusCallback
*iface
)
54 return CONTAINING_RECORD(iface
, bsc_t
, IBindStatusCallback_iface
);
57 static HRESULT WINAPI
bsc_QueryInterface(
58 IBindStatusCallback
*iface
,
62 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
63 IsEqualGUID(riid
, &IID_IBindStatusCallback
))
65 IBindStatusCallback_AddRef( iface
);
70 TRACE("interface %s not implemented\n", debugstr_guid(riid
));
75 static ULONG WINAPI
bsc_AddRef(
76 IBindStatusCallback
*iface
)
78 bsc_t
*bsc
= impl_from_IBindStatusCallback(iface
);
79 LONG ref
= InterlockedIncrement(&bsc
->ref
);
81 TRACE("%p, refcount %ld.\n", iface
, ref
);
86 static ULONG WINAPI
bsc_Release(
87 IBindStatusCallback
*iface
)
89 bsc_t
*bsc
= impl_from_IBindStatusCallback(iface
);
90 LONG ref
= InterlockedDecrement(&bsc
->ref
);
92 TRACE("%p, refcount %ld.\n", iface
, ref
);
97 IBinding_Release(bsc
->binding
);
99 IStream_Release(bsc
->memstream
);
106 static HRESULT WINAPI
bsc_OnStartBinding(
107 IBindStatusCallback
* iface
,
111 bsc_t
*This
= impl_from_IBindStatusCallback(iface
);
114 TRACE("%p, %lx, %p.\n", iface
, dwReserved
, pib
);
117 IBinding_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, %#lx, %s.\n", iface
, 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 This
->hres
= 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
*bsc
= impl_from_IBindStatusCallback(iface
);
204 TRACE("%p, %lx, %lu, %p, %p.\n", iface
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
208 hr
= IStream_Read(pstgmed
->pstm
, buf
, sizeof(buf
), &read
);
212 hr
= IStream_Write(bsc
->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
create_uri(IUri
*base
, const WCHAR
*url
, IUri
**uri
)
243 WCHAR fileUrl
[INTERNET_MAX_URL_LENGTH
];
246 TRACE("%s\n", debugstr_w(url
));
248 if (!PathIsURLW(url
))
250 WCHAR fullpath
[MAX_PATH
];
251 DWORD needed
= ARRAY_SIZE(fileUrl
);
253 lstrcpynW(fileUrl
, url
, ARRAY_SIZE(fileUrl
));
254 UrlUnescapeW(fileUrl
, NULL
, NULL
, URL_UNESCAPE_INPLACE
);
256 if (!PathSearchAndQualifyW(fileUrl
, fullpath
, ARRAY_SIZE(fullpath
)))
258 WARN("can't find path\n");
262 if (FAILED(UrlApplySchemeW(fullpath
, fileUrl
, &needed
, URL_APPLY_GUESSSCHEME
| URL_APPLY_GUESSFILE
|
265 ERR("Failed to apply url scheme.\n");
271 hr
= CreateUri(url
, Uri_CREATE_ALLOW_RELATIVE
| Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME
, 0, uri
);
272 if (hr
== S_OK
&& base
)
276 hr
= CoInternetCombineIUri(base
, *uri
, 0, &rebased_uri
, 0);
284 HRESULT
create_moniker_from_url(LPCWSTR url
, IMoniker
**mon
)
289 TRACE("%s\n", debugstr_w(url
));
291 if (FAILED(hr
= create_uri(NULL
, url
, &uri
)))
294 hr
= CreateURLMonikerEx2(NULL
, uri
, mon
, 0);
299 HRESULT
bind_url(IMoniker
*mon
, HRESULT (*onDataAvailable
)(void*,char*,DWORD
),
300 void *obj
, bsc_t
**ret
)
308 hr
= CreateBindCtx(0, &pbc
);
312 bsc
= heap_alloc(sizeof(bsc_t
));
314 bsc
->IBindStatusCallback_iface
.lpVtbl
= &bsc_vtbl
;
317 bsc
->onDataAvailable
= onDataAvailable
;
319 bsc
->memstream
= NULL
;
322 hr
= RegisterBindStatusCallback(pbc
, &bsc
->IBindStatusCallback_iface
, NULL
, 0);
326 hr
= IMoniker_BindToStorage(mon
, pbc
, NULL
, &IID_IStream
, (LPVOID
*)&stream
);
328 IStream_Release(stream
);
329 IBindCtx_Release(pbc
);
334 IBindStatusCallback_Release(&bsc
->IBindStatusCallback_iface
);
342 HRESULT
detach_bsc(bsc_t
*bsc
)
347 IBinding_Abort(bsc
->binding
);
351 IBindStatusCallback_Release(&bsc
->IBindStatusCallback_iface
);