rasapi32: Update spec file.
[wine/zf.git] / dlls / msxml3 / bsc.c
blob5cebe09333bf94a103fccc1a1489208f16b2e1e2
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;
56 HRESULT hres;
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,
66 REFIID riid,
67 LPVOID *ppobj )
69 if (IsEqualGUID(riid, &IID_IUnknown) ||
70 IsEqualGUID(riid, &IID_IBindStatusCallback))
72 IBindStatusCallback_AddRef( iface );
73 *ppobj = iface;
74 return S_OK;
77 TRACE("interface %s not implemented\n", debugstr_guid(riid));
78 *ppobj = NULL;
79 return E_NOINTERFACE;
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);
90 return 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);
101 if(!ref) {
102 if (This->binding) IBinding_Release(This->binding);
103 if (This->memstream) IStream_Release(This->memstream);
104 heap_free(This);
107 return ref;
110 static HRESULT WINAPI bsc_OnStartBinding(
111 IBindStatusCallback* iface,
112 DWORD dwReserved,
113 IBinding* pib)
115 bsc_t *This = impl_from_IBindStatusCallback(iface);
116 HRESULT hr;
118 TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
120 This->binding = pib;
121 IBinding_AddRef(pib);
123 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream);
124 if(FAILED(hr))
125 return hr;
127 return S_OK;
130 static HRESULT WINAPI bsc_GetPriority(
131 IBindStatusCallback* iface,
132 LONG* pnPriority)
134 return S_OK;
137 static HRESULT WINAPI bsc_OnLowResource(
138 IBindStatusCallback* iface,
139 DWORD reserved)
141 return S_OK;
144 static HRESULT WINAPI bsc_OnProgress(
145 IBindStatusCallback* iface,
146 ULONG ulProgress,
147 ULONG ulProgressMax,
148 ULONG ulStatusCode,
149 LPCWSTR szStatusText)
151 return S_OK;
154 static HRESULT WINAPI bsc_OnStopBinding(
155 IBindStatusCallback* iface,
156 HRESULT hresult,
157 LPCWSTR szError)
159 bsc_t *This = impl_from_IBindStatusCallback(iface);
160 HRESULT hr = S_OK;
162 TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
164 if(This->binding) {
165 IBinding_Release(This->binding);
166 This->binding = NULL;
169 if(This->obj && SUCCEEDED(hresult)) {
170 HGLOBAL hglobal;
171 hr = GetHGlobalFromStream(This->memstream, &hglobal);
172 if(SUCCEEDED(hr))
174 DWORD len = GlobalSize(hglobal);
175 char *ptr = GlobalLock(hglobal);
177 This->hres = This->onDataAvailable(This->obj, ptr, len);
179 GlobalUnlock(hglobal);
183 return hr;
186 static HRESULT WINAPI bsc_GetBindInfo(
187 IBindStatusCallback* iface,
188 DWORD* grfBINDF,
189 BINDINFO* pbindinfo)
191 *grfBINDF = BINDF_GETNEWESTVERSION|BINDF_PULLDATA|BINDF_RESYNCHRONIZE|BINDF_PRAGMA_NO_CACHE;
193 return S_OK;
196 static HRESULT WINAPI bsc_OnDataAvailable(
197 IBindStatusCallback* iface,
198 DWORD grfBSCF,
199 DWORD dwSize,
200 FORMATETC* pformatetc,
201 STGMEDIUM* pstgmed)
203 bsc_t *This = impl_from_IBindStatusCallback(iface);
204 BYTE buf[4096];
205 DWORD read, written;
206 HRESULT hr;
208 TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
212 hr = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read);
213 if(FAILED(hr))
214 break;
216 hr = IStream_Write(This->memstream, buf, read, &written);
217 } while(SUCCEEDED(hr) && written != 0 && read != 0);
219 return S_OK;
222 static HRESULT WINAPI bsc_OnObjectAvailable(
223 IBindStatusCallback* iface,
224 REFIID riid,
225 IUnknown* punk)
227 return S_OK;
230 static const struct IBindStatusCallbackVtbl bsc_vtbl =
232 bsc_QueryInterface,
233 bsc_AddRef,
234 bsc_Release,
235 bsc_OnStartBinding,
236 bsc_GetPriority,
237 bsc_OnLowResource,
238 bsc_OnProgress,
239 bsc_OnStopBinding,
240 bsc_GetBindInfo,
241 bsc_OnDataAvailable,
242 bsc_OnObjectAvailable
245 HRESULT create_uri(IUri *base, const WCHAR *url, IUri **uri)
247 WCHAR fileUrl[INTERNET_MAX_URL_LENGTH];
248 HRESULT hr;
250 TRACE("%s\n", debugstr_w(url));
252 if (!PathIsURLW(url))
254 WCHAR fullpath[MAX_PATH];
255 DWORD needed = ARRAY_SIZE(fileUrl);
257 lstrcpynW(fileUrl, url, ARRAY_SIZE(fileUrl));
258 UrlUnescapeW(fileUrl, NULL, NULL, URL_UNESCAPE_INPLACE);
260 if (!PathSearchAndQualifyW(fileUrl, fullpath, ARRAY_SIZE(fullpath)))
262 WARN("can't find path\n");
263 return E_FAIL;
266 if (FAILED(UrlApplySchemeW(fullpath, fileUrl, &needed, URL_APPLY_GUESSSCHEME | URL_APPLY_GUESSFILE |
267 URL_APPLY_DEFAULT)))
269 ERR("Failed to apply url scheme.\n");
270 return E_FAIL;
272 url = fileUrl;
275 hr = CreateUri(url, Uri_CREATE_ALLOW_RELATIVE | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, uri);
276 if (hr == S_OK && base)
278 IUri *rebased_uri;
280 hr = CoInternetCombineIUri(base, *uri, 0, &rebased_uri, 0);
281 IUri_Release(*uri);
282 *uri = rebased_uri;
285 return hr;
288 HRESULT create_moniker_from_url(LPCWSTR url, IMoniker **mon)
290 HRESULT hr;
291 IUri *uri;
293 TRACE("%s\n", debugstr_w(url));
295 if (FAILED(hr = create_uri(NULL, url, &uri)))
296 return hr;
298 hr = CreateURLMonikerEx2(NULL, uri, mon, 0);
299 IUri_Release(uri);
300 return hr;
303 HRESULT bind_url(IMoniker *mon, HRESULT (*onDataAvailable)(void*,char*,DWORD),
304 void *obj, bsc_t **ret)
306 bsc_t *bsc;
307 IBindCtx *pbc;
308 HRESULT hr;
310 TRACE("%p\n", mon);
312 hr = CreateBindCtx(0, &pbc);
313 if(FAILED(hr))
314 return hr;
316 bsc = heap_alloc(sizeof(bsc_t));
318 bsc->IBindStatusCallback_iface.lpVtbl = &bsc_vtbl;
319 bsc->ref = 1;
320 bsc->obj = obj;
321 bsc->onDataAvailable = onDataAvailable;
322 bsc->binding = NULL;
323 bsc->memstream = NULL;
324 bsc->hres = S_OK;
326 hr = RegisterBindStatusCallback(pbc, &bsc->IBindStatusCallback_iface, NULL, 0);
327 if(SUCCEEDED(hr))
329 IStream *stream;
330 hr = IMoniker_BindToStorage(mon, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
331 if(stream)
332 IStream_Release(stream);
333 IBindCtx_Release(pbc);
336 if(FAILED(hr))
338 IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface);
339 bsc = NULL;
342 *ret = bsc;
343 return hr;
346 HRESULT detach_bsc(bsc_t *bsc)
348 HRESULT hres;
350 if(bsc->binding)
351 IBinding_Abort(bsc->binding);
353 bsc->obj = NULL;
354 hres = bsc->hres;
355 IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface);
357 return hres;