ReactOS  0.4.14-dev-390-g34947ad
bsc.c
Go to the documentation of this file.
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 #ifdef HAVE_LIBXML2
26 # include <libxml/parser.h>
27 # include <libxml/xmlerror.h>
28 #endif
29 
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"
39 
40 #include "wine/debug.h"
41 
42 #include "msxml_private.h"
43 
45 
46 struct bsc_t {
48 
50 
51  void *obj;
52  HRESULT (*onDataAvailable)(void*,char*,DWORD);
53 
57 };
58 
60 {
61  return CONTAINING_RECORD(iface, bsc_t, IBindStatusCallback_iface);
62 }
63 
65  IBindStatusCallback *iface,
66  REFIID riid,
67  LPVOID *ppobj )
68 {
69  if (IsEqualGUID(riid, &IID_IUnknown) ||
70  IsEqualGUID(riid, &IID_IBindStatusCallback))
71  {
72  IBindStatusCallback_AddRef( iface );
73  *ppobj = iface;
74  return S_OK;
75  }
76 
77  TRACE("interface %s not implemented\n", debugstr_guid(riid));
78  *ppobj = NULL;
79  return E_NOINTERFACE;
80 }
81 
83  IBindStatusCallback *iface )
84 {
87 
88  TRACE("(%p) ref=%d\n", This, ref);
89 
90  return ref;
91 }
92 
94  IBindStatusCallback *iface )
95 {
98 
99  TRACE("(%p) ref=%d\n", This, ref);
100 
101  if(!ref) {
102  if (This->binding) IBinding_Release(This->binding);
103  if (This->memstream) IStream_Release(This->memstream);
104  heap_free(This);
105  }
106 
107  return ref;
108 }
109 
111  IBindStatusCallback* iface,
113  IBinding* pib)
114 {
116  HRESULT hr;
117 
118  TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
119 
120  This->binding = pib;
121  IBinding_AddRef(pib);
122 
123  hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream);
124  if(FAILED(hr))
125  return hr;
126 
127  return S_OK;
128 }
129 
131  IBindStatusCallback* iface,
132  LONG* pnPriority)
133 {
134  return S_OK;
135 }
136 
138  IBindStatusCallback* iface,
139  DWORD reserved)
140 {
141  return S_OK;
142 }
143 
145  IBindStatusCallback* iface,
146  ULONG ulProgress,
147  ULONG ulProgressMax,
148  ULONG ulStatusCode,
149  LPCWSTR szStatusText)
150 {
151  return S_OK;
152 }
153 
155  IBindStatusCallback* iface,
156  HRESULT hresult,
157  LPCWSTR szError)
158 {
160  HRESULT hr = S_OK;
161 
162  TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
163 
164  if(This->binding) {
165  IBinding_Release(This->binding);
166  This->binding = NULL;
167  }
168 
169  if(This->obj && SUCCEEDED(hresult)) {
170  HGLOBAL hglobal;
171  hr = GetHGlobalFromStream(This->memstream, &hglobal);
172  if(SUCCEEDED(hr))
173  {
174  DWORD len = GlobalSize(hglobal);
175  char *ptr = GlobalLock(hglobal);
176 
177  This->hres = This->onDataAvailable(This->obj, ptr, len);
178 
179  GlobalUnlock(hglobal);
180  }
181  }
182 
183  return hr;
184 }
185 
187  IBindStatusCallback* iface,
188  DWORD* grfBINDF,
189  BINDINFO* pbindinfo)
190 {
191  *grfBINDF = BINDF_GETNEWESTVERSION|BINDF_PULLDATA|BINDF_RESYNCHRONIZE|BINDF_PRAGMA_NO_CACHE;
192 
193  return S_OK;
194 }
195 
197  IBindStatusCallback* iface,
198  DWORD grfBSCF,
199  DWORD dwSize,
200  FORMATETC* pformatetc,
201  STGMEDIUM* pstgmed)
202 {
204  BYTE buf[4096];
205  DWORD read, written;
206  HRESULT hr;
207 
208  TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
209 
210  do
211  {
212  hr = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read);
213  if(FAILED(hr))
214  break;
215 
216  hr = IStream_Write(This->memstream, buf, read, &written);
217  } while(SUCCEEDED(hr) && written != 0 && read != 0);
218 
219  return S_OK;
220 }
221 
223  IBindStatusCallback* iface,
224  REFIID riid,
225  IUnknown* punk)
226 {
227  return S_OK;
228 }
229 
230 static const struct IBindStatusCallbackVtbl bsc_vtbl =
231 {
233  bsc_AddRef,
234  bsc_Release,
243 };
244 
246 {
248 
249  TRACE("%s\n", debugstr_w(url));
250 
251  if (!PathIsURLW(url))
252  {
253  WCHAR fullpath[MAX_PATH];
254  DWORD needed = ARRAY_SIZE(fileUrl);
255 
256  if (!PathSearchAndQualifyW(url, fullpath, ARRAY_SIZE(fullpath)))
257  {
258  WARN("can't find path\n");
259  return E_FAIL;
260  }
261 
262  if (FAILED(UrlCreateFromPathW(fullpath, fileUrl, &needed, 0)))
263  {
264  ERR("can't create url from path\n");
265  return E_FAIL;
266  }
267  url = fileUrl;
268  }
269 
270  return CreateUri(url, Uri_CREATE_ALLOW_RELATIVE | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, uri);
271 }
272 
274 {
275  HRESULT hr;
276  IUri *uri;
277 
278  TRACE("%s\n", debugstr_w(url));
279 
280  if (FAILED(hr = create_uri(url, &uri)))
281  return hr;
282 
283  hr = CreateURLMonikerEx2(NULL, uri, mon, 0);
284  IUri_Release(uri);
285  return hr;
286 }
287 
288 HRESULT bind_url(IMoniker *mon, HRESULT (*onDataAvailable)(void*,char*,DWORD),
289  void *obj, bsc_t **ret)
290 {
291  bsc_t *bsc;
292  IBindCtx *pbc;
293  HRESULT hr;
294 
295  TRACE("%p\n", mon);
296 
297  hr = CreateBindCtx(0, &pbc);
298  if(FAILED(hr))
299  return hr;
300 
301  bsc = heap_alloc(sizeof(bsc_t));
302 
303  bsc->IBindStatusCallback_iface.lpVtbl = &bsc_vtbl;
304  bsc->ref = 1;
305  bsc->obj = obj;
306  bsc->onDataAvailable = onDataAvailable;
307  bsc->binding = NULL;
308  bsc->memstream = NULL;
309  bsc->hres = S_OK;
310 
311  hr = RegisterBindStatusCallback(pbc, &bsc->IBindStatusCallback_iface, NULL, 0);
312  if(SUCCEEDED(hr))
313  {
314  IStream *stream;
315  hr = IMoniker_BindToStorage(mon, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
316  if(stream)
317  IStream_Release(stream);
318  IBindCtx_Release(pbc);
319  }
320 
321  if(FAILED(hr))
322  {
323  IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface);
324  bsc = NULL;
325  }
326 
327  *ret = bsc;
328  return hr;
329 }
330 
332 {
333  HRESULT hres;
334 
335  if(bsc->binding)
336  IBinding_Abort(bsc->binding);
337 
338  bsc->obj = NULL;
339  hres = bsc->hres;
340  IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface);
341 
342  return hres;
343 }
static HRESULT WINAPI bsc_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
Definition: bsc.c:196
#define HRESULT
Definition: msvc.h:9
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
HRESULT WINAPI GetHGlobalFromStream(IStream *pstm, HGLOBAL *phglobal)
#define E_NOINTERFACE
Definition: winerror.h:2364
static const struct IBindStatusCallbackVtbl bsc_vtbl
Definition: bsc.c:230
HRESULT hr
Definition: shlfolder.c:183
HRESULT create_uri(const WCHAR *url, IUri **uri)
Definition: bsc.c:245
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
const char * uri
Definition: sec_mgr.c:1594
REFIID riid
Definition: precomp.h:44
static HRESULT WINAPI bsc_OnProgress(IBindStatusCallback *iface, ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
Definition: bsc.c:144
#define WARN(fmt,...)
Definition: debug.h:111
static HRESULT WINAPI bsc_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
Definition: bsc.c:137
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
WINE_DEFAULT_DEBUG_CHANNEL(msxml)
IBindStatusCallback IBindStatusCallback_iface
Definition: bsc.c:47
#define E_FAIL
Definition: ddrawi.h:102
#define DWORD
Definition: nt_native.h:44
Definition: send.c:47
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
LONG ref
Definition: bsc.c:49
static ULONG WINAPI bsc_Release(IBindStatusCallback *iface)
Definition: bsc.c:93
BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
Definition: url.c:2432
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
HRESULT create_moniker_from_url(LPCWSTR url, IMoniker **mon)
Definition: bsc.c:273
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
long LONG
Definition: pedump.c:60
#define debugstr_w
Definition: kernel32.h:32
Definition: bsc.c:46
GLenum GLint ref
Definition: glext.h:6028
static PVOID ptr
Definition: dispmode.c:27
r reserved
Definition: btrfs.c:2865
HRESULT detach_bsc(bsc_t *bsc)
Definition: bsc.c:331
static HRESULT WINAPI bsc_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved, IBinding *pib)
Definition: bsc.c:110
static IBindStatusCallbackEx bsc
Definition: url.c:2149
HRESULT bind_url(IMoniker *mon, HRESULT(*onDataAvailable)(void *, char *, DWORD), void *obj, bsc_t **ret)
Definition: bsc.c:288
smooth NULL
Definition: ftsmooth.c:416
#define INTERNET_MAX_URL_LENGTH
Definition: session.c:1380
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc, IBindStatusCallback **ppbscPrevious, DWORD dwReserved)
Definition: bindctx.c:615
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC *ppbc)
Definition: bindctx.c:556
HRESULT(* onDataAvailable)(void *, char *, DWORD)
Definition: bsc.c:52
__wchar_t WCHAR
Definition: xmlstorage.h:180
HRESULT WINAPI UrlCreateFromPathW(LPCWSTR pszPath, LPWSTR pszUrl, LPDWORD pcchUrl, DWORD dwReserved)
Definition: url.c:2497
LONG HRESULT
Definition: typedefs.h:77
static const WCHAR url[]
Definition: encode.c:1432
const GUID IID_IUnknown
static HRESULT WINAPI bsc_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
Definition: bsc.c:154
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
static HRESULT WINAPI bsc_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
Definition: bsc.c:222
int ret
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define InterlockedDecrement
Definition: armddk.h:52
static ULONG WINAPI bsc_AddRef(IBindStatusCallback *iface)
Definition: bsc.c:82
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
void * obj
Definition: bsc.c:51
HRESULT WINAPI CreateURLMonikerEx2(IMoniker *pmkContext, IUri *pUri, IMoniker **ppmk, DWORD dwFlags)
Definition: umon.c:668
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
static bsc_t * impl_from_IBindStatusCallback(IBindStatusCallback *iface)
Definition: bsc.c:59
#define ERR(fmt,...)
Definition: debug.h:109
#define S_OK
Definition: intsafe.h:59
#define InterlockedIncrement
Definition: armddk.h:53
HRESULT hres
Definition: bsc.c:56
#define ARRAY_SIZE(a)
Definition: main.h:24
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
IStream * memstream
Definition: bsc.c:55
BOOL WINAPI PathSearchAndQualifyW(LPCWSTR lpszPath, LPWSTR lpszBuf, UINT cchBuf)
Definition: path.c:3205
HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IUri **ppURI)
Definition: uri.c:5701
static HRESULT WINAPI bsc_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
Definition: bsc.c:130
unsigned int ULONG
Definition: retypes.h:1
static HRESULT WINAPI bsc_QueryInterface(IBindStatusCallback *iface, REFIID riid, LPVOID *ppobj)
Definition: bsc.c:64
IBinding * binding
Definition: bsc.c:54
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
static HRESULT WINAPI bsc_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
Definition: bsc.c:186
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static BOOL heap_free(void *mem)
Definition: appwiz.h:75