d3d9/tests: Add some tests for IDirect3DDevice9::UpdateSurface().
[wine/wine-gecko.git] / dlls / msxml3 / bsc.c
blob9a8be97c9cacca01553ea4055b3316ce43e29291
1 /*
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
19 #define COBJMACROS
20 #define NONAMELESSUNION
22 #include "config.h"
24 #include <stdarg.h>
25 #ifdef HAVE_LIBXML2
26 # include <libxml/parser.h>
27 # include <libxml/xmlerror.h>
28 #endif
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winuser.h"
33 #include "ole2.h"
34 #include "msxml6.h"
35 #include "wininet.h"
36 #include "urlmon.h"
37 #include "winreg.h"
38 #include "shlwapi.h"
40 #include "wine/debug.h"
42 #include "msxml_private.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
46 struct bsc_t {
47 IBindStatusCallback IBindStatusCallback_iface;
49 LONG ref;
51 void *obj;
52 HRESULT (*onDataAvailable)(void*,char*,DWORD);
54 IBinding *binding;
55 IStream *memstream;
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,
65 REFIID riid,
66 LPVOID *ppobj )
68 if (IsEqualGUID(riid, &IID_IUnknown) ||
69 IsEqualGUID(riid, &IID_IBindStatusCallback))
71 IBindStatusCallback_AddRef( iface );
72 *ppobj = iface;
73 return S_OK;
76 TRACE("interface %s not implemented\n", debugstr_guid(riid));
77 *ppobj = NULL;
78 return E_NOINTERFACE;
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);
89 return 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);
100 if(!ref) {
101 if (This->binding) IBinding_Release(This->binding);
102 if (This->memstream) IStream_Release(This->memstream);
103 heap_free(This);
106 return ref;
109 static HRESULT WINAPI bsc_OnStartBinding(
110 IBindStatusCallback* iface,
111 DWORD dwReserved,
112 IBinding* pib)
114 bsc_t *This = impl_from_IBindStatusCallback(iface);
115 HRESULT hr;
117 TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
119 This->binding = pib;
120 IBinding_AddRef(pib);
122 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream);
123 if(FAILED(hr))
124 return hr;
126 return S_OK;
129 static HRESULT WINAPI bsc_GetPriority(
130 IBindStatusCallback* iface,
131 LONG* pnPriority)
133 return S_OK;
136 static HRESULT WINAPI bsc_OnLowResource(
137 IBindStatusCallback* iface,
138 DWORD reserved)
140 return S_OK;
143 static HRESULT WINAPI bsc_OnProgress(
144 IBindStatusCallback* iface,
145 ULONG ulProgress,
146 ULONG ulProgressMax,
147 ULONG ulStatusCode,
148 LPCWSTR szStatusText)
150 return S_OK;
153 static HRESULT WINAPI bsc_OnStopBinding(
154 IBindStatusCallback* iface,
155 HRESULT hresult,
156 LPCWSTR szError)
158 bsc_t *This = impl_from_IBindStatusCallback(iface);
159 HRESULT hr = S_OK;
161 TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
163 if(This->binding) {
164 IBinding_Release(This->binding);
165 This->binding = NULL;
168 if(This->obj && SUCCEEDED(hresult)) {
169 HGLOBAL hglobal;
170 hr = GetHGlobalFromStream(This->memstream, &hglobal);
171 if(SUCCEEDED(hr))
173 DWORD len = GlobalSize(hglobal);
174 char *ptr = GlobalLock(hglobal);
176 hr = This->onDataAvailable(This->obj, ptr, len);
178 GlobalUnlock(hglobal);
182 return hr;
185 static HRESULT WINAPI bsc_GetBindInfo(
186 IBindStatusCallback* iface,
187 DWORD* grfBINDF,
188 BINDINFO* pbindinfo)
190 *grfBINDF = BINDF_GETNEWESTVERSION|BINDF_PULLDATA|BINDF_RESYNCHRONIZE|BINDF_PRAGMA_NO_CACHE;
192 return S_OK;
195 static HRESULT WINAPI bsc_OnDataAvailable(
196 IBindStatusCallback* iface,
197 DWORD grfBSCF,
198 DWORD dwSize,
199 FORMATETC* pformatetc,
200 STGMEDIUM* pstgmed)
202 bsc_t *This = impl_from_IBindStatusCallback(iface);
203 BYTE buf[4096];
204 DWORD read, written;
205 HRESULT hr;
207 TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
211 hr = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read);
212 if(FAILED(hr))
213 break;
215 hr = IStream_Write(This->memstream, buf, read, &written);
216 } while(SUCCEEDED(hr) && written != 0 && read != 0);
218 return S_OK;
221 static HRESULT WINAPI bsc_OnObjectAvailable(
222 IBindStatusCallback* iface,
223 REFIID riid,
224 IUnknown* punk)
226 return S_OK;
229 static const struct IBindStatusCallbackVtbl bsc_vtbl =
231 bsc_QueryInterface,
232 bsc_AddRef,
233 bsc_Release,
234 bsc_OnStartBinding,
235 bsc_GetPriority,
236 bsc_OnLowResource,
237 bsc_OnProgress,
238 bsc_OnStopBinding,
239 bsc_GetBindInfo,
240 bsc_OnDataAvailable,
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];
247 bsc_t *bsc;
248 IBindCtx *pbc;
249 HRESULT hr;
251 TRACE("%s\n", debugstr_w(url));
253 if(!PathIsURLW(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");
261 return E_FAIL;
264 if(FAILED(UrlCreateFromPathW(url, fileUrl, &needed, 0)))
266 ERR("can't create url from path\n");
267 return E_FAIL;
269 url = fileUrl;
272 hr = CreateBindCtx(0, &pbc);
273 if(FAILED(hr))
274 return hr;
276 bsc = heap_alloc(sizeof(bsc_t));
278 bsc->IBindStatusCallback_iface.lpVtbl = &bsc_vtbl;
279 bsc->ref = 1;
280 bsc->obj = obj;
281 bsc->onDataAvailable = onDataAvailable;
282 bsc->binding = NULL;
283 bsc->memstream = NULL;
285 hr = RegisterBindStatusCallback(pbc, &bsc->IBindStatusCallback_iface, NULL, 0);
286 if(SUCCEEDED(hr))
288 IMoniker *moniker;
290 hr = CreateURLMoniker(NULL, url, &moniker);
291 if(SUCCEEDED(hr))
293 IStream *stream;
294 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
295 IMoniker_Release(moniker);
296 if(stream)
297 IStream_Release(stream);
299 IBindCtx_Release(pbc);
302 if(FAILED(hr))
304 IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface);
305 bsc = NULL;
308 *ret = bsc;
309 return hr;
312 void detach_bsc(bsc_t *bsc)
314 if(bsc->binding)
315 IBinding_Abort(bsc->binding);
317 bsc->obj = NULL;
318 IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface);