~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/msxml3/bsc.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Copyright 2008 Piotr Caban
  3  *
  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.
  8  *
  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.
 13  *
 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
 17  */
 18 
 19 #define COBJMACROS
 20 #define NONAMELESSUNION
 21 
 22 #include "config.h"
 23 
 24 #include <stdarg.h>
 25 #include <assert.h>
 26 #include "windef.h"
 27 #include "winbase.h"
 28 #include "winuser.h"
 29 #include "ole2.h"
 30 #include "msxml2.h"
 31 #include "wininet.h"
 32 #include "urlmon.h"
 33 #include "winreg.h"
 34 #include "shlwapi.h"
 35 
 36 #include "wine/debug.h"
 37 
 38 #include "msxml_private.h"
 39 
 40 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
 41 
 42 struct bsc_t {
 43     const struct IBindStatusCallbackVtbl *lpVtbl;
 44 
 45     LONG ref;
 46 
 47     void *obj;
 48     HRESULT (*onDataAvailable)(void*,char*,DWORD);
 49 
 50     IBinding *binding;
 51     IStream *memstream;
 52 };
 53 
 54 static inline bsc_t *impl_from_IBindStatusCallback( IBindStatusCallback *iface )
 55 {
 56     return (bsc_t *)((char*)iface - FIELD_OFFSET(bsc_t, lpVtbl));
 57 }
 58 
 59 static HRESULT WINAPI bsc_QueryInterface(
 60     IBindStatusCallback *iface,
 61     REFIID riid,
 62     LPVOID *ppobj )
 63 {
 64     if (IsEqualGUID(riid, &IID_IUnknown) ||
 65         IsEqualGUID(riid, &IID_IBindStatusCallback))
 66     {
 67         IBindStatusCallback_AddRef( iface );
 68         *ppobj = iface;
 69         return S_OK;
 70     }
 71 
 72     TRACE("interface %s not implemented\n", debugstr_guid(riid));
 73     return E_NOINTERFACE;
 74 }
 75 
 76 static ULONG WINAPI bsc_AddRef(
 77     IBindStatusCallback *iface )
 78 {
 79     bsc_t *This = impl_from_IBindStatusCallback(iface);
 80     LONG ref = InterlockedIncrement(&This->ref);
 81 
 82     TRACE("(%p) ref=%d\n", This, ref);
 83 
 84     return ref;
 85 }
 86 
 87 static ULONG WINAPI bsc_Release(
 88     IBindStatusCallback *iface )
 89 {
 90     bsc_t *This = impl_from_IBindStatusCallback(iface);
 91     LONG ref = InterlockedDecrement(&This->ref);
 92 
 93     TRACE("(%p) ref=%d\n", This, ref);
 94 
 95     if(!ref) {
 96         if(This->binding)
 97             IBinding_Release(This->binding);
 98         if(This->memstream)
 99             IStream_Release(This->memstream);
100         HeapFree(GetProcessHeap(), 0, This);
101     }
102 
103     return ref;
104 }
105 
106 static HRESULT WINAPI bsc_OnStartBinding(
107         IBindStatusCallback* iface,
108         DWORD dwReserved,
109         IBinding* pib)
110 {
111     bsc_t *This = impl_from_IBindStatusCallback(iface);
112     HRESULT hr;
113 
114     TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
115 
116     This->binding = pib;
117     IBinding_AddRef(pib);
118 
119     hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream);
120     if(FAILED(hr))
121         return hr;
122 
123     return S_OK;
124 }
125 
126 static HRESULT WINAPI bsc_GetPriority(
127         IBindStatusCallback* iface,
128         LONG* pnPriority)
129 {
130     return S_OK;
131 }
132 
133 static HRESULT WINAPI bsc_OnLowResource(
134         IBindStatusCallback* iface,
135         DWORD reserved)
136 {
137     return S_OK;
138 }
139 
140 static HRESULT WINAPI bsc_OnProgress(
141         IBindStatusCallback* iface,
142         ULONG ulProgress,
143         ULONG ulProgressMax,
144         ULONG ulStatusCode,
145         LPCWSTR szStatusText)
146 {
147     return S_OK;
148 }
149 
150 static HRESULT WINAPI bsc_OnStopBinding(
151         IBindStatusCallback* iface,
152         HRESULT hresult,
153         LPCWSTR szError)
154 {
155     bsc_t *This = impl_from_IBindStatusCallback(iface);
156     HRESULT hr = S_OK;
157 
158     TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
159 
160     if(This->binding) {
161         IBinding_Release(This->binding);
162         This->binding = NULL;
163     }
164 
165     if(This->obj && SUCCEEDED(hresult)) {
166         HGLOBAL hglobal;
167         hr = GetHGlobalFromStream(This->memstream, &hglobal);
168         if(SUCCEEDED(hr))
169         {
170             DWORD len = GlobalSize(hglobal);
171             char *ptr = GlobalLock(hglobal);
172 
173             hr = This->onDataAvailable(This->obj, ptr, len);
174 
175             GlobalUnlock(hglobal);
176         }
177     }
178 
179     return hr;
180 }
181 
182 static HRESULT WINAPI bsc_GetBindInfo(
183         IBindStatusCallback* iface,
184         DWORD* grfBINDF,
185         BINDINFO* pbindinfo)
186 {
187     *grfBINDF = BINDF_GETNEWESTVERSION|BINDF_PULLDATA|BINDF_RESYNCHRONIZE|BINDF_PRAGMA_NO_CACHE;
188 
189     return S_OK;
190 }
191 
192 static HRESULT WINAPI bsc_OnDataAvailable(
193         IBindStatusCallback* iface,
194         DWORD grfBSCF,
195         DWORD dwSize,
196         FORMATETC* pformatetc,
197         STGMEDIUM* pstgmed)
198 {
199     bsc_t *This = impl_from_IBindStatusCallback(iface);
200     BYTE buf[4096];
201     DWORD read, written;
202     HRESULT hr;
203 
204     TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
205 
206     do
207     {
208         hr = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read);
209         if(FAILED(hr))
210             break;
211 
212         hr = IStream_Write(This->memstream, buf, read, &written);
213     } while(SUCCEEDED(hr) && written != 0 && read != 0);
214 
215     return S_OK;
216 }
217 
218 static HRESULT WINAPI bsc_OnObjectAvailable(
219         IBindStatusCallback* iface,
220         REFIID riid,
221         IUnknown* punk)
222 {
223     return S_OK;
224 }
225 
226 static const struct IBindStatusCallbackVtbl bsc_vtbl =
227 {
228     bsc_QueryInterface,
229     bsc_AddRef,
230     bsc_Release,
231     bsc_OnStartBinding,
232     bsc_GetPriority,
233     bsc_OnLowResource,
234     bsc_OnProgress,
235     bsc_OnStopBinding,
236     bsc_GetBindInfo,
237     bsc_OnDataAvailable,
238     bsc_OnObjectAvailable
239 };
240 
241 HRESULT bind_url(LPCWSTR url, HRESULT (*onDataAvailable)(void*,char*,DWORD), void *obj, bsc_t **ret)
242 {
243     WCHAR fileUrl[INTERNET_MAX_URL_LENGTH];
244     bsc_t *bsc;
245     IBindCtx *pbc;
246     HRESULT hr;
247 
248     TRACE("%s\n", debugstr_w(url));
249 
250     if(!PathIsURLW(url))
251     {
252         WCHAR fullpath[MAX_PATH];
253         DWORD needed = sizeof(fileUrl)/sizeof(WCHAR);
254 
255         if(!PathSearchAndQualifyW(url, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
256         {
257             WARN("can't find path\n");
258             return E_FAIL;
259         }
260 
261         if(FAILED(UrlCreateFromPathW(url, fileUrl, &needed, 0)))
262         {
263             ERR("can't create url from path\n");
264             return E_FAIL;
265         }
266         url = fileUrl;
267     }
268 
269     hr = CreateBindCtx(0, &pbc);
270     if(FAILED(hr))
271         return hr;
272 
273     bsc = HeapAlloc(GetProcessHeap(), 0, sizeof(bsc_t));
274 
275     bsc->lpVtbl = &bsc_vtbl;
276     bsc->ref = 1;
277     bsc->obj = obj;
278     bsc->onDataAvailable = onDataAvailable;
279     bsc->binding = NULL;
280     bsc->memstream = NULL;
281 
282     hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&bsc->lpVtbl, NULL, 0);
283     if(SUCCEEDED(hr))
284     {
285         IMoniker *moniker;
286 
287         hr = CreateURLMoniker(NULL, url, &moniker);
288         if(SUCCEEDED(hr))
289         {
290             IStream *stream;
291             hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
292             IMoniker_Release(moniker);
293             if(stream)
294                 IStream_Release(stream);
295         }
296         IBindCtx_Release(pbc);
297     }
298 
299     if(FAILED(hr))
300     {
301         IBindStatusCallback_Release((IBindStatusCallback*)&bsc->lpVtbl);
302         bsc = NULL;
303     }
304 
305     *ret = bsc;
306     return hr;
307 }
308 
309 void detach_bsc(bsc_t *bsc)
310 {
311     if(bsc->binding)
312         IBinding_Abort(bsc->binding);
313 
314     bsc->obj = NULL;
315     IBindStatusCallback_Release((IBindStatusCallback*)&bsc->lpVtbl);
316 }
317 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.